Leetcode刷題筆記(python3版)

EASY LEVEL:

1108. Defanging an IP Address

題目:Given a valid (IPv4) IP address, return a defanged version of that IP address. A defanged IP address replaces every period "." with "[.]".

Example 1:

Input: address = "1.1.1.1"
Output: "1[.]1[.]1[.]1"

這道題其實就是把中間的'.'變成‘[.]’而已:

class Solution:
    def defangIPaddr(self, address: str) -> str:
        x = '[.]'.join(address.split(sep='.'))
        return(x)

join相當於join一個string

 

771. Jewels and Stones

You're given strings J representing the types of stones that are jewels, and S representing the stones you have.  Each character in S is a type of stone you have.  You want to know how many of the stones you have are also jewels.

The letters in J are guaranteed distinct, and all characters in J and S are letters. Letters are case sensitive, so "a" is considered a different type of stone from "A".

Example 1:

Input: J = "aA", S = "aAAbbbb"
Output: 3

此道題是看J中的字母在S中出現的次數的總和:

1.在S中數一下每個出現字母的次數並分別求和; 2. 循環遍歷J,把每個字母對應的加上。

class Solution:
    def numJewelsInStones(self, J: str, S: str) -> int:
        c = 0
        for i in range(len(J)):
            c = c+ sum(map(J[i].count, S))
        return c

map()函數的使用。

 

938. Range Sum of BST

Given the root node of a binary search tree, return the sum of values of all nodes with value between L and R(inclusive).

The binary search tree is guaranteed to have unique values.

Example 1:

Input: root = [10,5,15,3,7,null,18], L = 7, R = 15
Output: 32

這道題用到了遞歸的思想。畫出這棵BST:

假設二叉樹頂點值爲V,可以分成三種情況:

1. V<L: 那麼頂點所有左子樹都小於L,需要去右子樹找到大於L並小於R的值;

2. V>R:那麼頂點所有右子樹都大於R,需要去左子樹找到大於L並小於R的值;

3.L<=V<=R: 這樣左右子樹都要找,因爲頂點也包括在這個範圍之內。

代碼:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def rangeSumBST(self, root: TreeNode, L: int, R: int) -> int:
        if not root:
            return 0
        result = 0
        if root.val > R:
            #root = root.right
            result = result + self.rangeSumBST(root.left, L, R)
        elif root.val < L:
            #root = root.left
            result = result + self.rangeSumBST(root.right, L, R)
        elif L <= root.val <= R:
            result = result + root.val
            result = result + self.rangeSumBST(root.left, L, R) 
            result = result+ self.rangeSumBST(root.right, L, R)
        return result

需要了解在什麼時候使用遞歸的思想!

 

709. To Lower Case

Implement function ToLowerCase() that has a string parameter str, and returns the same string in lowercase.

Example 1:

Input: "Hello"
Output: "hello"

非常簡單的一道題,無需多說

class Solution:
    def toLowerCase(self, str: str) -> str:
        st = str.lower()
        return st
        

 

1021. Remove Outermost Parentheses

A valid parentheses string is either empty ("")"(" + A + ")", or A + B, where A and B are valid parentheses strings, and + represents string concatenation.  For example, """()""(())()", and "(()(()))" are all valid parentheses strings.

A valid parentheses string S is primitive if it is nonempty, and there does not exist a way to split it into S = A+B, with A and B nonempty valid parentheses strings.

Given a valid parentheses string S, consider its primitive decomposition: S = P_1 + P_2 + ... + P_k, where P_iare primitive valid parentheses strings.

Return S after removing the outermost parentheses of every primitive string in the primitive decomposition of S.

Example 1:

Input: "(()())(())"
Output: "()()()"
Explanation: 
The input string is "(()())(())", with primitive decomposition "(()())" + "(())".
After removing outer parentheses of each part, this is "()()" + "()" = "()()()".

我的想法是,對 '(' 和 ')' 進行計數,開始會有兩種情況:"((" 和 "()",第一個出現的一定是"("並且一定是最後要被移除的。我們只要找到原來string裏面需要移除的字符串位置就可以。設定一個count是left(計算"("的個數),一個count是right(計算")"的個數),那麼從第二個字符開始計數的時候,只要left == right,說明到達了一個全部括號都回頭的狀態,那麼這個位置就是需要被移除的位置。而所有需要被移除的位置有三種: 第一個+括號回頭的位置+括號回頭的下一個位置(如果沒有超過字符串長度的話)。

class Solution:
    def removeOuterParentheses(self, S: str) -> str:
        str_x = list(S)
        rmv = [0]
        left = 0
        right = 0
        for i in range(len(str_x)):
            if str_x[i] == '(':
                left +=1
            elif str_x[i] == ')':
                right +=1
            if left == right:
                rmv.append(i)
                if i<(len(str_x)-1): 
                    rmv.append(i+1)
        index_list = [int(i) for i in rmv] 
        str_new = [v for i,v in enumerate(str_x) if i not in index_list]
        str_final = "".join(str_new)
        return(str_final)
       

還有用棧來實現的,也很值得借鑑:

class Solution:
    def removeOuterParentheses(self, S: str) -> str:
        res = ''
        stack = []
        # basket is used to store previous value
        basket = ''
        for p in S:
            if p == '(':
                stack.append(p)
            else:
                stack.pop()
            basket += p
            
            # if the stack is empty it means we have a valid
            # decomposition. remove the outer parentheses
            # and put it in the result/res. make sure to
            # clean up the basket though!
            if not stack:
                res += basket[1:-1]
                basket = ''
                
        return res

要多多使用方便的數據結構!

 

804. Unique Morse Code Words

International Morse Code defines a standard encoding where each letter is mapped to a series of dots and dashes, as follows: "a" maps to ".-""b" maps to "-...""c" maps to "-.-.", and so on.

For convenience, the full table for the 26 letters of the English alphabet is given below:

[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]

Now, given a list of words, each word can be written as a concatenation of the Morse code of each letter. For example, "cba" can be written as "-.-..--...", (which is the concatenation "-.-." + "-..." + ".-"). We'll call such a concatenation, the transformation of a word.

Return the number of different transformations among all words we have.

Example:
Input: words = ["gin", "zen", "gig", "msg"]
Output: 2
Explanation: 
The transformation of each word is:
"gin" -> "--...-."
"zen" -> "--...-."
"gig" -> "--...--."
"msg" -> "--...--."

There are 2 different transformations, "--...-." and "--...--.".

Note:

  • The length of words will be at most 100.
  • Each words[i] will have length in range [1, 12].
  • words[i] will only consist of lowercase letters.

 

此題如果用python的字典功能會很好解決,把每個字母map到字典裏面去,得到他們的莫斯編碼,最後unique一下就得到了結果。

class Solution:
    def uniqueMorseRepresentations(self, words: List[str]) -> int:
        map = [".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]
        alb = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]
        # 把對應關係封裝到字典裏面
        edict = dict(zip(alb, map))

        res = set()
        for word in words:
            mword = ""
            for w in word:
                mword = mword + edict[w]
            res.add(mword)
        return len(res)

 

832. Flipping an Image

Given a binary matrix A, we want to flip the image horizontally, then invert it, and return the resulting image.

To flip an image horizontally means that each row of the image is reversed.  For example, flipping [1, 1, 0] horizontally results in [0, 1, 1].

To invert an image means that each 0 is replaced by 1, and each 1 is replaced by 0. For example, inverting [0, 1, 1] results in [1, 0, 0].

Example 1:

Input: [[1,1,0],[1,0,1],[0,0,0]]
Output: [[1,0,0],[0,1,0],[1,1,1]]
Explanation: First reverse each row: [[0,1,1],[1,0,1],[0,0,0]].
Then, invert the image: [[1,0,0],[0,1,0],[1,1,1]]

Notes:

  • 1 <= A.length = A[0].length <= 20
  • 0 <= A[i][j] <= 1

這道題我的想法是分兩步:1.把每個元素都倒序一下;2.把每個元素的0變成1,1變成0

class Solution:
    def flipAndInvertImage(self, A: List[List[int]]) -> List[List[int]]:
        s_new = []
        for s in range(len(A)):
            A[s].reverse()
            # 因爲怕把1直接變成0,全部的都是0就找不到原來的0,所以先變成2
            s_f = [2 if x==1 else x for x in A[s]]
            s_f = [1 if x==0 else x for x in s_f]
            s_f = [0 if x==2 else x for x in s_f]
            s_new.append(s_f)
        return(s_new)

其實還是搞複雜了,網上有一行的代碼很值得學習:

class Solution:
	def flipAndInvertImage(self, A: List[List[int]]) -> List[List[int]]:
		return [[1 - x for x in i] for i in [i[::-1] for i in A]] 
		
		```
		nested list comprehensions - firstly it reversed the list and then invert 1 with 0 (each item less 1 with absolute value)
		```

 

905. Sort Array By Parity

Given an array A of non-negative integers, return an array consisting of all the even elements of A, followed by all the odd elements of A.

You may return any answer array that satisfies this condition.

Example 1:

Input: [3,1,2,4]
Output: [2,4,3,1]
The outputs [4,2,3,1], [2,4,1,3], and [4,2,1,3] would also be accepted.

這道題只需要先把偶數找出來然後並上奇數就可以:
 

class Solution:
    def sortArrayByParity(self, A: List[int]) -> List[int]:
        return [i for i in A if i % 2 ==0]+[i for i in A if i % 2 != 0]

 

961. N-Repeated Element in Size 2N Array

In a array A of size 2N, there are N+1 unique elements, and exactly one of these elements is repeated N times.

Return the element repeated N times.

Example 1:

Input: [1,2,3,3]
Output: 3

說實話這題一開始想的是把所有的數一遍然後找出count>2的,最後運行出來時間太慢了。。。原來的代碼:

class Solution:
    def repeatedNTimes(self, A: List[int]) -> int:
        dup = [x for x in A if A.count(x) >1]
        return(dup[0])

後來想,其實不需要知道一個重複的元素出現了幾次,根本不需要count,只需要在出現第一個重複的時候把那個重複的元素返回回來就好了。。。

所以新建了一個新的list,每次加一個元素進去,到第i次的時候遍歷原來數組從第i+1到最後一個元素,看看有沒有重複的,因爲題目說數組裏只有一個重複的元素,所以如果找到第一個重複的數一定是唯一的那個,也不用管它後面出現了幾次,直接return回來其實就可以了,這樣算法複雜度就下降了不少。

class Solution:
    def repeatedNTimes(self, A: List[int]) -> int:
        A_new = []
        for i in range(len(A)-1):
            A_new.append(A[i])
            for j in range((i+1),len(A)):
                if A[j] in A_new:
                    return(A[j])

看排名最高的參考答案是利用了字典。。。看來我還是不熟悉。。

from collections import Counter

class Solution:
	def repeatedNTimes(self, A: List[int]) -> int:
		rep_dic = dict(Counter(A))                     # Creates dictionary with number of repetitions
		for key in rep_dic:
			if rep_dic[key] == len(A)/2: return key    # When value equals N, return key

字典的概念需要非常瞭解!

 

657. Robot Return to Origin

There is a robot starting at position (0, 0), the origin, on a 2D plane. Given a sequence of its moves, judge if this robot ends up at (0, 0) after it completes its moves.

The move sequence is represented by a string, and the character moves[i] represents its ith move. Valid moves are R (right), L (left), U (up), and D (down). If the robot returns to the origin after it finishes all of its moves, return true. Otherwise, return false.

Note: The way that the robot is "facing" is irrelevant. "R" will always make the robot move to the right once, "L" will always make it move left, etc. Also, assume that the magnitude of the robot's movement is the same for each move.

Example 1:

Input: "UD"
Output: true 
Explanation: The robot moves up once, and then down once. All moves have the same magnitude, so it ended up at the origin where it started. Therefore, we return true.

這題其實就是L的個數和R相等,U的個數和D相等,那麼它就回到原點。

class Solution:
    def judgeCircle(self, moves: str) -> bool:

        A = list(moves)
        # 分別計算LRUD有幾個
        L_final = [x for x in A if x == 'L']
        R_final = [x for x in A if x == 'R']
        U_final = [x for x in A if x == 'U']
        D_final = [x for x in A if x == 'D']
        if((len(L_final)==len(R_final))&(len(U_final)==len(D_final))):
            return True
        return False

其實我還是寫複雜了。。。看來python還不是特別熟。。

class Solution:
	def judgeCircle(self, moves: str) -> bool:
		return (moves.count('D') == moves.count('U') and moves.count('L') == moves.count('R'))
	    # string.count() counts occurances in a string

string.count()這個函數需要掌握!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章