LeetCode刷題記錄(python3)

因爲以前對算法題接觸很少,所以暫時只作easy和medium難度的題.node

看完了《算法(第四版)》後從新開始刷LeetCode了,此次決定按topic來刷題,有一個大體的方向.有些題不止包含在一個topic中,就以我本身作的前後順序爲準了.python

Array

---11.Container With Most Water

給定許多條與y軸平行的直線,求其中兩條直線與x軸圍成的容器的最大容量.git

這道題用到了雙指針的思想.咱們在數軸的兩端分別放置一個left指針和right指針,由於容器容量=較短邊*兩邊位置之差,因此若是移動較大的那個指針,那麼容量一定在減少.所以咱們不斷往中間移動較小的指針纔有可能使容量變大,直到兩指針相遇爲止.算法

對於算法合理性的邏輯推理:咱們假設在best_left和best_right位置取到最大容量,那麼left指針到達best_left位置或right指針到達best_right位置至少有一種會發生.不妨令left指針到達best_left位置,此時right指針的位置有三種可能:segmentfault

  1. 位於best_right位置左側.這說明best_right位置已經被計算過,成立.
  2. 位於best_right位置,同上.
  3. 位於best_right位置右側.由於left指針移動的條件是right指針所在邊大於left指針所在邊,若是符合此條件,且right指針在best_right右側,那麼當前容量必定大於假設中的最大容量,與假設矛盾.因此left指針一定會一路移動至best_right位置.
class Solution(object):
    def maxArea(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        left = 0
        right = len(height) - 1
        
        most = 0
        while left != right:
            h = min(height[left], height[right])
            most = max(most, h * (right - left))
            if height[left] < height[right]:
                left += 1
            else:
                right -=1
       
        return most

Container With Most Water
Container With Most Water

---16.3Sum Closest

給定一個數組和一個目標值,找到數組中的三個數,使得這三個數之和與目標值之間的差距最小,返回它們的和.數組

這題的思路與15題相似,也是利用雙指針,只不過斷定條件從三個數之和是否爲零改爲了三個數之和是否比目前已有的closest值更接近目標.app

class Solution:
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        closest = nums[0] + nums[1] + nums[2]
        nums.sort()
        length = len(nums)
        for i in range(length):
            l = i + 1
            r = length - 1
            while l < r:
                tmp = nums[i] + nums[l] + nums[r]
                if tmp == target:
                    closest = target
                    break
                elif tmp < target:
                    if target - tmp < abs(target - closest):
                        closest = tmp
                    l += 1
                elif tmp > target:
                    if tmp - target < abs(target - closest):
                        closest = tmp
                    r -= 1
        return closest

3Sum Closest
3Sum Closest

 

---18.4Sum

找出list中全部相加等於target的4個數的list.ide

一開始個人思路是令new_target=target-num1,而後轉換爲一個3Sum問題,但這種作法的時間複雜度過高了.查看Solution後發現這道題要使用hash的思想,在python中對應的實現就是使用先dict存儲list中的兩數之和和它們在list中的位置,而後對於這個dict中的value,尋找一個key=target-value,而後將他們對應的數字存入list便可.須要注意的是python中的list,set,dict是不可哈希的,int,float,str,tuple是可哈希的.函數

class Solution:
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        d = dict()
        for i in range(len(nums)):
            for j in range(i+1,len(nums)):
                sum2 = nums[i]+nums[j]
                if sum2 in d:
                    d[sum2].append((i,j))
                else:
                    d[sum2] = [(i,j)]
        
        result = []
        for key in d:
            value = target - key
            if value in d:
                list1 = d[key]
                list2 = d[value]
                for (i,j) in list1:
                    for (k,l) in list2:
                        if i!=k and i!=l and j!=k and j!=l:
                            flist = [nums[i],nums[j],nums[k],nums[l]]
                            flist.sort()
                            if flist not in result:
                                result.append(flist)
        return result
4Sum

 

---35.Search Insert Position

給定一個有序list和一個數target,求這個數在這個list中的位置.post

有序,立刻想到了二分查找,只不過要針對找不到的狀況進行一下特殊處理.普通的二分查找在找不到時返回的是-1,咱們這裏只要返回找不到時傳入函數的left就好了.

class Solution:
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        def bs(numlsit, l, r):
            while l <= r:
                mid = int((l + r) / 2)
                if numlsit[mid] == target:
                    return mid
                elif numlsit[mid] < target:
                    return bs(numlsit, mid+1, r)
                else:
                    return bs(numlsit, l, mid-1)
            return l
        
        return bs(nums, 0, len(nums)-1)
Search Insert Position

 

---41.First Missing Positive

給定一個無序list,求出其中缺失的最小正整數,要求時間複雜度O(n).

設list長度爲l的話,最後的答案確定是1~l+1之間的一個正整數,因此想到了設置標誌數組flag,flag[i]爲1表示i+1已經出現過了.遍歷一次list後再遍歷一次flag,遇到的第一個0的index就是答案.若是遍歷完整個flag都沒有輸出值,說明答案是l+1.

class Solution:
    def firstMissingPositive(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if nums == []:
            return 1
        l = len(nums)
        pi = [0] * l
        for i in range(l):
            tmp = nums[i]
            if tmp > 0 and tmp <= l:
                pi[tmp-1] = 1
        for i in range(l):
            if pi[i] == 0:
                return i+1
        return l+1
First Missing Positive

 

---45.Jump Game II

給定一個非負整數list,初始位置在list[0],list的值表明了該位置能向前走的最大步數,求走到list末尾所需的最小次數(假設必定可以走到末尾).

既然要求最小次數,那麼目的就是每一步都儘量地往前走.這裏的"儘量"並不是是每一步都走能走的最大步數,而是走到的位置加上該位置的最大步數,這表明了咱們下一步的選擇範圍.理清這一點後代碼就很簡單了.

class Solution:
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        l = len(nums)
        pos = 0
        sum = 0

        def find_next(pos):
            next = 0
            pace = nums[pos]
            max = 0
            if pos + pace >= l - 1:
                next = l - 1
            else:
                for i in range(1, pace+1):
                    tmp = i + nums[pos+i]
                    if tmp > max:
                        max = tmp
                        next = pos + i
            return next

        while pos < l - 1:
            pos = find_next(pos)
            sum += 1
            
        return sum
Jump Game II

 

---55.Jump Game

給定一個非負整數list,初始位置在list[0],list的值表明了該位置能向前走的最大步數,求是否能走到list末尾.

這道題和45題相似,咱們仍然採用45題的走法,可是加入一個斷定條件,若是走到了list[i]=0的位置說明不可以走到終點,輸出False,不然輸出True.

class Solution:
    def canJump(self, nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        l = len(nums)
        pos = 0
        sum = 0

        def find_next(pos):
            next = 0
            pace = nums[pos]
            max = 0
            if pos + pace >= l - 1:
                next = l - 1
            else:
                for i in range(1, pace + 1):
                    tmp = i + nums[pos + i]
                    if tmp > max:
                        max = tmp
                        next = pos + i
            return next

        while pos < l - 1:
            if nums[pos] == 0:
                return False
            pos = find_next(pos)
            sum += 1

        return True
Jump Game

 

---59.Spiral Matrix II

給定一個正整數n,生成一個n*n的矩陣,其中元素按照螺旋形從1一直到n^2

觀察這個生成的矩陣,會發現每一圈都是從左上角開始,沿着順時針方向遞增的規律生成的.按照這個思路,咱們定義一個circle函數,它每次都在n*n的矩陣中生成一圈符合條件的數.這個函數接受三個參數,分別表明了出發點,邊長還有初始值.其中出發點從(0,0)開始,每次增長(1,1),邊長從n開始每次-2,初始值能夠經過函數中加入數字的次數獲得.

class Solution:
    def generateMatrix(self, n):
        """
        :type n: int
        :rtype: List[List[int]]
        """
        spiral = [[0 for i in range(n)] for j in range(n)]

        def circle(start, length, initial):
            sum = 0
            for i in range(length):
                spiral[start][start+i] = i + 1 + initial
                sum += 1
            for i in range(length-1):
                spiral[start+i+1][start+length-1] = i + length + 1 + initial
                sum += 1
            for i in range(length-1):
                spiral[start+length-1][start+length-i-2] = i + 2 * length + initial
                sum +=1
            for i in range(length-2):
                spiral[start+length-i-2][start] = i + 3 * length - 1 + initial
                sum += 1
            return sum

        times = int((n+1)/2)
        sum = 0
        for i in range(times):
            sum += circle(i, n-2*i, sum)


        return spiral
Spiral Matrix II

 

---63.Unique Paths II

給定一個m*n的矩陣,其中0表明能夠走的路,1表明障礙物.機器人只能往下或往右走,初始位置在矩陣左上角,求可讓機器人走到矩陣右下角的路徑的數量.

一開始想用深度優先遍歷解決,後來發現太費時間,因而想到了動態規劃.公式以下:

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid):
        """
        :type obstacleGrid: List[List[int]]
        :rtype: int
        """
        m = len(obstacleGrid)
        n = len(obstacleGrid[0])

        dp = [[0 for i in range(n)] for j in range(m)]

        dp[0][0] = 0 if obstacleGrid[0][0] == 1 else 1

        for i in range(m):
            for j in range(n):
                if obstacleGrid[i][j] == 1:
                    dp[i][j] == 0
                else:
                    if i-1 >= 0:
                        dp[i][j] += dp[i-1][j]
                    if j-1 >= 0:
                        dp[i][j] += dp[i][j-1]

        return dp[m-1][n-1]
Unique Paths II

 

---64.Minimum Path Sum

給定一個m*n的非負矩陣,矩陣中的數字表明權值,起點在矩陣左上角,只能往右或往下走,求走到矩陣右下角所需的最小路徑長度.

基本的動態規劃題,dp[0][0]=grid[0][0],dp[i][j]=grid[i][j]+min(dp[i-1][j],dp[i][j-1]),第一排和第一列因爲沒有上/左的格子,須要提早處理.

class Solution:
    def minPathSum(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        m = len(grid)
        n = len(grid[0])
        dp = [[0 for i in range(n)] for j in range(m)]
        dp[0][0] = grid[0][0]

        for i in range(1,n):
            dp[0][i] = grid[0][i] + dp[0][i-1]

        for i in range(1,m):
            dp[i][0] = grid[i][0] + dp[i-1][0]

        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])
        
        return dp[-1][-1]
Minimum Path Sum

 

---66.Plus One

給定一個非空的個位數數組,這個數組總體表明瞭一個非負整數.將這個非負整數+1後用個位數數組的形式返回.

思路比較簡單,就是將數組中的數分別取出乘上位數後相加,再將這個數+1後存入另外一個數組.值得注意的是python雖然支持大數運算,但若是超出了2^63-1的範圍後用int()類型轉換會丟失一部分值,因此要在運算過程當中轉換爲字符串來處理.

class Solution:
    def plusOne(self, digits):
        """
        :type digits: List[int]
        :rtype: List[int]
        """
        plus = []
        sum = 0
        l = len(digits)
        for i in range(l):
            sum *= 10
            sum += digits[i]

        sum += 1
        while sum != '' and sum > 0:
            plus.insert(0,sum%10)
            sum = str(sum)[:-1]
            if sum != '':
                sum = int(sum)

        return plus
        
Plus One

提交事後雖然AC了,可是運算速度較慢,查看了Solution後發現這題應該用加法器的思想來作,有進位則本位置0,保留進位.

class Solution:
    def plusOne(self, digits):
        """
        :type digits: List[int]
        :rtype: List[int]
        """
        p = 1
        for i in range(len(digits), 0 , -1):
            r = digits[i-1] + p
            if r >= 10:
                p = 1
                digits[i-1] = 0
            else:
                p = 0
                digits[i-1] = r
        if p == 1: 
            digits = [1] + digits
        return digits 
                        
        
Plus One

 

---73. Set Matrix Zeroes

給定一個m*n的矩陣matrix,若是有一個元素是0,則將該元素的所在行和列都變爲0.要求in-palce就地操做實現,也就是不使用臨時變量,空間複雜度O(1).

空間複雜度O(MN)的解法:新建一個m*n的矩陣,掃描matrix,掃到0就在新矩陣對應行和列賦0,最後把新矩陣賦給matrix

空間複雜度O(M+N)的解法:新建一個長度爲M的數組記錄每一行是否有0,一個長度爲N的數組記錄每一列是否有0

空間複雜度O(1)的解法:利用matrix自己記錄,首先定義row_flag和column_flag表示矩陣的第一行和第一列是否有0,而後掃描矩陣除了第一行和第一列之外的部分,用第一行和第一列置0來表示有0.

class Solution:
    def setZeroes(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: void Do not return anything, modify matrix in-place instead.
        """
        m = len(matrix)
        n = len(matrix[0])
        row_flag = False
        col_flag = False
        for i in range(n):
            if matrix[0][i] == 0:
                row_flag = True

        for i in range(m):
            if matrix[i][0] == 0:
                col_flag = True

        for i in range(1,m):
            for j in range(1,n):
                if matrix[i][j] == 0:
                    matrix[i][0] = 0
                    matrix[0][j] = 0

        for i in range(1,m):
            for j in range(1,n):
                if matrix[i][0] == 0 or matrix[0][j] == 0:
                    matrix[i][j] = 0

        if row_flag:
            for i in range(n):
                matrix[0][i] = 0

        if col_flag:
            for i in range(m):
                matrix[i][0] = 0
Set Matrix Zeros

 

---74.Search a 2D Matrix

給定一個m*n的整數矩陣,其中每行數從左到右升序排列,而且知足每行的第一個數大於上一行的最後一個數,給定一個target,肯定target是否在這個矩陣中.

看見有序仍是先想到二分查找,由於每一行之間實際也隱含着順序了,因此只要先根據每一行的最後一個數判斷出咱們想要查找的是哪一行,而後對那一行進行二分查找便可.注意[]和[[]]的特殊狀況.

class Solution:
    def searchMatrix(self, matrix, target):
        """
        :type matrix: List[List[int]]
        :type target: int
        :rtype: bool
        """
        
        def binary_search(numlist, l, r, t):
            while l <= r:
                mid = int((l + r) / 2)
                if numlist[mid] == t:
                    return True
                elif numlist[mid] < t:
                    return binary_search(numlist, mid+1, r, t)
                else:
                    return binary_search(numlist, l, mid-1, t)
            return False

        if matrix == [] or matrix == [[]]:
            return False
        
        if target < matrix[0][0] or target > matrix[-1][-1]:
            return False


        m = len(matrix)
        n = len(matrix[0])


        for i in range(m):
            if matrix[i][-1] >= target:
                return binary_search(matrix[i], 0, n-1, target)
Search a 2D Matrix

 

---78.Subsets

給定一個不含重複元素的數組,返回該數組可能的全部子集

一開始想到用遞歸來作,在list中記錄s,而後遍歷s中的每一個元素i,使用s-i來遞歸,可是隻要數組元素稍微多一點就超時,顯然是時間複雜度過高了.

查閱資料後發現這道題應該用回溯法+深度優先遍歷,以[1,2,3]爲例,第一層元素爲[],第二層元素爲[1],[2],[3],每深刻一層就要刪除剛剛加入的元素,直到數組裏的元素所有用完後再回溯:

class Solution:
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """        
        l = [[]]


        def dfs(nums, index, path, li):
            for i in range(index, len(nums)):
                li.append(path+[nums[i]])
                path.append(nums[i])
                dfs(nums, i+1, path, li)
                path.pop()

                
        if nums is None:
            return []
        dfs(nums, 0, [], l)
        return l
Subsets

 

---79.Word Search

給定一個二維list和一個word,判斷這個word是否能用二維list中相鄰的字母鏈接而成(不能重複使用)

一道dfs題目,終止條件是當全部字母找完時返回True,當沒找完而且四個方向都不能繼續走下去時返回False.找到一個字母后分別向四個方向走,若是其中一個方向返回True則總體爲True.走過的位置設爲'#',當四個方向都回來後將'#'從新變回原來的字母.

class Solution:
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """

        m = len(board)
        n = len(board[0])
        l = len(word)

        def near(grid, i, j, word, pos):
            if pos == l:
                return True
            if i-1 < -1 or i+1 > m or j-1 < -1 or j+1 > n or word[pos] != grid[i][j]:
                return False
            tmp = board[i][j]
            board[i][j] = '#'
            res = near(grid, i+1, j, word, pos+1) or near(grid, i-1, j, word, pos+1)\
                  or near(grid, i, j+1, word, pos+1) or near(grid, i, j-1, word, pos+1)
            board[i][j] = tmp
            return res



        for i in range(m):
            for j in range(n):
                if near(board, i, j, word, 0):
                    return True
        return False
79. Word Search

 

---80.Remove Duplicates from Sorted Array II

給定一個有序list,使得其中的數字不能重複出現兩次以上,要求in-place作法,返回值爲處理後的數組的長度

由於要求in-place,因此先用一個for循環找出重複兩次以上的數字的位置,將它們改成'#',而後在第二次for循環刪去這些'#'.注意這一次的循環要用倒序,不然會由於刪去元素致使索引不正確而出錯.

class Solution:
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if nums == []:
            return 0
        l = len(nums)
        dup = 0
        tmp = nums[0]
        for i in range(1,l):
            if nums[i] == tmp:
                dup += 1
            else:
                dup = 0
                tmp = nums[i]
            if dup >= 2:
                nums[i] = '#'

        for i in range(l-1, -1, -1):
            if nums[i] == '#':
                nums.pop(i)
                
        return len(nums)

        

        
80. Remove Duplicates from Sorted Array II

 

---81.Search in Rotated Sorted Array II

給定一個list,是由一個有序數組在某一樞紐處旋轉獲得的,而且其中可能含有重複元素,要求判斷target是否在這個list中.

雖然這個list通過旋轉,可是仍是能夠用二分查找的思想,由於mid的左邊或右邊必定有一端是有序的.所以只須要在二分查找的時候對此進行判斷就好了.另外本題可能有重複值,因此當left,mid和right指向的值都相等時要移動指針來跳出循環.

class Solution:
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: bool
        """
        left = 0
        right = len(nums)-1

        while left <= right:
            mid = int((left + right) / 2)
            if nums[mid] == target:
                return True

            if nums[mid] < nums[right] or nums[mid] < nums[left]:
                if nums[mid] < target <= nums[right]:
                    left = mid + 1
                else:
                    right = mid - 1
            elif nums[mid] > nums[left] or nums[mid] > nums[right]:
                if nums[mid] > target >= nums[left]:
                    right = mid - 1
                else:
                    left = mid + 1
            else:
                left += 1

        return False
81. Search in Rotated Sorted Array II

 

---105.Construct Binary Tree from Preorder and Inorder Traversal

給定二叉樹的前序遍歷和中序遍歷,輸出該二叉樹

前序遍歷也就是根-左-右,中序遍歷就是左-根-右.咱們用遞歸的方式,preorder[0]一定是根結點,而這個根結點在inorder中的位置的左邊是它的左子樹,右邊是它的右子樹.只要抓住這個關鍵點就能夠了.

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

class Solution:
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        if len(preorder) == 0:return None
        root_node = TreeNode(preorder[0])
        j = inorder.index(preorder[0])
        root_node.left  = self.buildTree(preorder[1:j+1],inorder[0:j])
        root_node.right = self.buildTree(preorder[j+1:],inorder[j+1:])
        return root_node
105. Construct Binary Tree from Preorder and Inorder Traversal

 

---106.Construct Binary Tree from Inorder and Postorder Ttaversal

給定二叉樹的中序遍歷和後序遍歷,輸出該二叉樹

中序遍歷是左-根-右,後序遍歷是左-右-根.preorder[-1]一定是根結點.而後就和105題相似了.

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

class Solution:
    def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        if len(postorder) == 0:return None
        root_node = TreeNode(postorder[-1])
        j = inorder.index(postorder[-1])
        root_node.left  = self.buildTree(inorder[0:j], postorder[0:j])
        root_node.right = self.buildTree(inorder[j+1:],postorder[j:-1])
        return root_node
106. Construct Binary Tree from Inorder and Postorder Traversal

 

---119.Pascal's Triangle II

楊輝三角問題,給定k,要求輸出楊輝三角的第k行

雖然看似是等腰三角形,但其實咱們能夠把它看作一個直角三角形,也就是矩陣的下半部分.這題若是用O(k^2)的空間的話很是簡單,抓住t[i][j] = t[i-1][j]+t[i-1][j-1]便可.題幹給了一個挑戰,是用O(k)的空間完成,其實也很是簡單,只要設置兩個臨時變量,分別存儲咱們要修改的位置的上一層的這一位和前一位便可(邏輯上的上層,實際上只有一維數組).

class Solution:
    def getRow(self, rowIndex):
        """
        :type rowIndex: int
        :rtype: List[int]
        """

        size = rowIndex+1

        tri = [0] * size
        tri[0] = 1

        for i in range(1,size):
            t1 = 1
            for j in range(1,size):
                t2 = tri[j]
                tri[j] = tri[j] + t1
                t1 = t2
        return tri
119. Pascal's Triangle II

 

---120.Triangle

給定一個三角形的list,求出從頂到底的最短路徑.

經典DP題,很是簡單.DP算式爲 tri[n-1][i] += min(tri[n][i], tri[n][i+1])

class Solution:
    def minimumTotal(self, triangle):
        """
        :type triangle: List[List[int]]
        :rtype: int
        """

        def dp(tri, n):
            if n < 1:
                return
            for i in range(n):
                tri[n-1][i] += min(tri[n][i], tri[n][i+1])
            dp(tri, n-1)


        dp(triangle, len(triangle)-1)
        return triangle[0][0]
120. Triangle

 

---152.Maximum Product Subarray

給定一個list,找出其中一個連續的子數組,使得其中全部數的乘積最大.

首先對整個數組求積,若是大於0則這就是答案,若是小於0則遍歷數組,若是找到0則對0左右的數組重複上述操做,若是找到負數則求負數兩邊的乘積之和.

class Solution:
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """

        def product(nums):
            if len(nums) == 0:
                return 0
            s = 1
            for x in nums:
                s *= x
            return s


        def find_max(nums):
            pro = product(nums)
            if pro > 0:
                return pro
            else:
                for i in range(len(nums)):
                    if nums[i] == 0:
                        return max(0, find_max(nums[:i]), find_max(nums[i+1:]))
                    if nums[i] < 0:
                        if len(nums[:i]) > 0:
                            pro_left = product(nums[:i])
                        else:
                            pro_left = pro
                        if len(nums[i+1:]) > 0:
                            pro_right = product(nums[i+1:])
                        else:
                            pro_right = pro
                        pro = max(pro, pro_left, pro_right)
                return pro
        
        
        if len(nums) == 1:
            return nums[0]
        
        pro = find_max(nums)
        return pro



        
152. Maximum Product Subarray

 

---153.Find Minimum in Rotated Sorted Array

給定一個排序過的list,在某一結點旋轉過,找出其中的最小值

相似81題,仍是用二分查找的思想.雖然list被旋轉過,可是left-mid和mid-right其中的一段一定是有序的.

class Solution:
    def findMin(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        l = len(nums)
        left = 0
        right = l-1
        mid = (left+right)//2

        while left < right:
            if nums[right] < nums[mid]:
                left = mid+1
            else:
                right = mid
            mid = (left+right)//2

        return min(nums[left], nums[right])
Find Minimum in Rotated Sorted Array

 

---167.Two Sum II - Input array is sorted

給定一個排序過的list,從中找到和等於target的兩個數的位置,返回它們以1爲起始值的座標.

雙指針的思想,比較簡單.值得一提的是,若是須要從無序數組中找到是否有兩數之和等於某一target,也是採用先排序再雙指針的方法.

class Solution:
    def twoSum(self, numbers, target):
        """
        :type numbers: List[int]
        :type target: int
        :rtype: List[int]
        """
        l = 0
        r = len(numbers) - 1
        while l < r:
            if numbers[l] + numbers[r] > target:
                r -= 1
            elif numbers[l] + numbers[r] < target:
                l += 1
            else:
                break
                
        ans = [l+1, r+1]
        return ans
Two Sum II - Input array is sorted

 

---189.Rotate Array

給定一個list和一個k,使這個list旋轉k步

利用python的切片便可

class Solution:
    def rotate(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        l = len(nums)
        k = k % l
        nums[:] = nums[l-k:] + nums[:l-k]
Rotate Array

 

---209.Minimum Size Subarray Sum

給定一個list和一個正數s,找到list中和大於等於s的最小連續區間的長度.若是沒有則返回0.

個人思路是雙指針法,用一個滑動的窗口去匹配,若是窗口內的值大於等於s則左移左邊框,不然右移右邊框,直到右邊框到達數組底部而且窗口值小於s位置.

class Solution:
    def minSubArrayLen(self, s, nums):
        """
        :type s: int
        :type nums: List[int]
        :rtype: int
        """
        if sum(nums) < s:
            return 0
        elif max(nums) >= s:
            return 1

        l, r = 0, 1
        add = nums[0] + nums[1]
        minimum = len(nums)

        while l < len(nums):
            if add >= s:
                tmp = r-l+1
                minimum = min(minimum, tmp)
                add -= nums[l]
                l += 1
            else:
                if r < len(nums)-1:
                    r += 1
                    add += nums[r]
                else:
                    break

        return minimum
Minimum Size Subarray Sum

 

---216.Combination Sum III

給定一個數k和一個數n,要求找到1-9內的k個數,且知足它們的和爲n的全部可能組合.

這道題是回溯法的應用.回溯法至關於有剪枝的DFS.思路是:保存當前步驟,若是是一個解就輸出;維護狀態,使搜索路徑(含子路徑)儘可能不重複.必要時,應該對不可能爲解的部分進行剪枝.

  • 遞歸函數的開頭寫好跳出條件,知足條件纔將當前結果加入總結果中
  • 已經拿過的數再也不拿
  • 遍歷過當前結點後,爲了回溯到上一步,要去掉已經加入到結果list中的當前結點.

代入到這題中,每個dfs都遍歷1-9中當前index後面的數,這確保了已經拿過的數再也不拿.進入下一層dfs,並令k-1,n-nums[index],跳出條件是k<0或n<0,知足條件是k==0且n==0.

class Solution:
    def combinationSum3(self, k, n):
        """
        :type k: int
        :type n: int
        :rtype: List[List[int]]
        """
        nums = [1,2,3,4,5,6,7,8,9]
        res = []

        def dfs(nums, k, n, index, path, res):
            if k < 0 or n < 0:
                return
            if k == 0 and n == 0:
                res.append(path)
            for i in range(index, len(nums)):
                dfs(nums, k-1, n-nums[i], i+1, path+[nums[i]], res)

        dfs(nums, k, n, 0, [], res)
        return res
Combination Sum III

 

---228.Summary Ranges

給定一個有序且無重複數字的list,將其中連續範圍的數字合併後返回

根據題意,咱們須要確認的其實就是每段連續區間的首尾數字.首數字多是list的第一個數或是前一個數和它不連續的數,尾數字多是list的最後一個數或是後一個數和它不連續的數.而且每個尾數字必定對應着一段連續區間,將這段區間存入一個字符list便可.

class Solution:
    def summaryRanges(self, nums):
        """
        :type nums: List[int]
        :rtype: List[str]
        """
        summary = []
        start = 0
        end = 0
        for i in range(len(nums)):
            if i == 0 or nums[i-1]+1 != nums[i]:
                start = nums[i]
            if i == len(nums)-1 or nums[i+1]-1 != nums[i]:
                end = nums[i]
                if start == end:
                    summary.append(str(start))
                else:
                    summary.append(str(start)+'->'+str(end))

        return summary
Summary Ranges

 

---229.Majority Element II

給定一個長度爲n的list,找到其中出現次數大於[n/3]的全部數.要求時間複雜度O(n),空間複雜度O(1).

個人想法是使用dict存儲這個list中每一個數出現的次數,而後將其中次數大於[n/3]的存入一個list.可是則不符合空間複雜度的要求.

查閱solution後發現這題可使用Boyer-Moore多數投票算法解決.這是一種尋找"多數元素"的好方法,基本思想是創建標誌位和count,若是匹配到的數字不等於標誌位則讓count-1,不然count+1,若是count爲0時更換標誌位.由於本題要求的是出現次數大於[n/3]的全部數,也就是最多可能有兩個數,所以要創建兩組標誌位和count.

class Solution:
    def majorityElement(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        count1, count2, tmp1, tmp2 = 0, 0, 0, 1
        for i in nums:
            if i == tmp1:
                count1 += 1
            elif i == tmp2:
                count2 += 1
            elif count1 == 0:
                tmp1 = i
                count1 = 1
            elif count2 == 0:
                tmp2 = i
                count2 = 1
            else:
                count1 -= 1
                count2 -= 1

        ans = [n for n in (tmp1, tmp2) if nums.count(n) > len(nums) // 3]
        return ans
Majority Element II

 

---283.Move Zeroes

給定一個list,將其中全部的0移到末尾,而且保持其餘元素的順序不變.要求in-place完成.

若是咱們採用的是交換位置或是移動0的話,index的變化將很是繁瑣.因此咱們將思路放在非零元素上:老是將非零元素與第一個零元素交換位置,每一次交換後將對應第一個零元素的index+1便可.

 

Dynamic Programming

---95.Unique Binary Search Trees II

給定一個數字n,生成全部存儲了1~n的二叉查找樹的可能形式.

這題的思路是每次選取一個結點做爲根,而後根據這個根把樹切分爲左右兩個子樹,再在左右兩個子樹裏選取結點做爲根,直至子樹爲空.注意子樹爲空時要返回[None]而不是[],不然循環沒法進行.

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

class Solution:
    def generateTrees(self, n):
        """
        :type n: int
        :rtype: List[TreeNode]
        """
        def dfs(nums):
            if not nums:
                return [None]
            result = []
            for i in range(len(nums)):
                for l in dfs(nums[:i]):
                    for r in dfs(nums[i+1:]):
                        node = TreeNode(nums[i])
                        node.left, node.right = l, r
                        result.append(node)
            return result

        nums = list(range(1,n+1))
        if n == 0:
            return []
        return dfs(nums)
        
 
        
Unique Binary Search Trees II

 

---198.House Robber

給定一個list,表明一條街道上每棟房子裏的財物.咱們要儘量多地搶這些財物,可是不能搶相鄰的兩棟房子.

遞推式是:

  1. f(0)=nums[0]
  2. f(1)=max(nums[0], nums[1])
  3. f(k)=max(f(k-1), f(k)+f(k-2))
class Solution:
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        elif len(nums) == 1:
            return nums[0]
        else:
            nums[1] = max(nums[0], nums[1])
            for i in range(2,len(nums)):
                nums[i] = max(nums[i]+nums[i-2], nums[i-1])

        return nums[-1]
House Robber

 

---213.House Robber II

給定一個list,表明一條街道上每棟房子裏的財物.咱們要儘量多地搶這些財物,可是不能搶相鄰的兩棟房子.這個街道是環形的.

這題和198很像,區別只是增長了一個第一棟房子與最後一棟房子不能同時搶的斷定.因此咱們分爲兩種狀況,同時爲了節省空間,採用了臨時變量:

  1. 搶了第一棟房子,此時問題變爲198題的求0~N-1
  2. 沒有搶第一棟房子,此時問題變爲198題的求1~N
class Solution:
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        elif len(nums) < 4:
            return max(nums)
        else:
            pplast, plast = 0, 0
            for i in nums[:-1]:
                tmp = plast
                plast = max(pplast+i, plast)
                pplast = tmp
            result = plast
            pplast, plast = 0, 0
            for i in nums[1:]:
                tmp = plast
                plast = max(pplast+i, plast)
                pplast = tmp
            return max(result, plast)
House Robber II

 

---264.Ugly Number II

找到第n個ugly number(質因數只有2,3,5的數字,包括1)

由於ugly number的質因數只有3種可能性,因此每個ugly number必定是由另外一個ugly number乘上這三個數的其中之一獲得的(1除外).因此想到了設立3個標誌位,分別表明2,3,5的乘數在數組中的位置,判斷它們的乘積最小者就是下一個ugly number.

class Solution:
    def nthUglyNumber(self, n):
        """
        :type n: int
        :rtype: int
        """
        ugly = [1]
        tmp_2, tmp_3, tmp_5 = 0, 0, 0



        for i in range(1,n):
            tmp = min(2*ugly[tmp_2], 3*ugly[tmp_3], 5*ugly[tmp_5])
            if tmp == 2*ugly[tmp_2]:
                tmp_2 += 1
            if tmp == 3*ugly[tmp_3]:
                tmp_3 += 1
            if tmp == 5*ugly[tmp_5]:
                tmp_5 += 1
            ugly.append(tmp)
            
        return ugly[-1]
Ugly Number II

 

---279.Perfect Squares

給定一個正整數n,找到相加之和等於它所需的徹底平方數的最小個數.

只要找到表達式dp[i]=min(dp[i],dp[i-j*j])就能夠了.

class Solution:
    def numSquares(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n == 0:
            return 0
        dp = list(range(0,n+1))
        dp[1] = 1
        for i in range(1,n+1):
            j = 1
            while j*j <= i:
                dp[i] = min(dp[i], dp[i-j*j]+1)
                j += 1

        return dp[-1]
Perfect Squares

 

---300.Longest Increasing Subsequence

給定一個無序list,找出其中最長的遞增子序列

dp的思路是比較容易想到的,使用一個dp數組存儲該位置的遞增子序列長度,dp[0]=1,對於i,遍歷全部小於i的j,只要nums[j]<nums[i],就使用表達式dp[i]=max(dp[i], dp[j]+1)來更新dp數組. 時間複雜度是O(n^2)

class Solution:
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        l = len(nums)
        if l < 2:
            return l
        dp = [1 for i in range(l)]
        for i in range(l):
            tmp = nums[i]
            for j in range(i):
               if nums[j] < tmp:
                   dp[i] = max(dp[i], dp[j]+1)
        return max(dp)
Longest Increasing Subsequence

另外一種在評論區看到的思路是使用一個tails數組,它的第i位表明的是nums中長度爲i的遞增子序列的最小數值.易得tails是一個遞增數組.而後對於每個數x,若是它比tails[-1]大,就在tails數組中增長一位,若是它知足tails[i-1] < x <= tails[i],就更新tails[i]=x.這樣作的好處是能夠用二分查找來肯定x的位置.這種作法的時間複雜度是O(nlogn)

def lengthOfLIS(self, nums):
    tails = [0] * len(nums)
    size = 0
    for x in nums:
        i, j = 0, size
        while i != j:
            m = (i + j) / 2
            if tails[m] < x:
                i = m + 1
            else:
                j = m
        tails[i] = x
        size = max(i + 1, size)
    return size
Longest Increasing Subsequence

 

---309.Best Time to Buy and Sell Stock with Cooldown

給定一個list表明股票價格,要求賣完股票後的第一天不能買入股票,求買賣能夠產生的最大利潤.

一開始沒有思路,在discuss看到這實際上是一道狀態轉移的問題.總共有hold,notHold,cooldown三種狀態,它們之間的轉移方程以下:

  1. hold---不操做---hold
  2. hold---賣股票---cooldown
  3. notHold---不操做---notHold
  4. notHold---買股票---hold
  5. cooldown---不操做---notHold

初始狀態是notHold,而後只要遍歷prices的list便可.

class Solution:
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        hold = float('-inf')
        notHold = 0
        cooldown = float('-inf')
        for p in prices:
            hold = max(hold, notHold-p)
            notHold = max(notHold, cooldown)
            cooldown = hold+p

        return max(notHold, hold, cooldown)
Best Time to Buy and Sell Stock with Cooldown

 

---322.Coin Change

給定一個list表明不一樣面值的錢,和一個總數amount,求出能湊出amount所需的錢的最小數量,若是湊不齊則返回-1.

找到表達式dp[i]=min(dp[i-coin]+1),注意湊不齊的金額設爲float('inf')便可.

class Solution:
    def coinChange(self, coins, amount):
        """
        :type coins: List[int]
        :type amount: int
        :rtype: int
        """
        MAX = float('inf')
        dp = [0] + [MAX] * amount

        for i in range(1, amount + 1):
            dp[i] = min([dp[i - c] if i - c >= 0 else MAX for c in coins]) + 1

        return [dp[amount], -1][dp[amount] == MAX]
        
Coin Change

 

---338.Counting Bits

給定一個非負整數num,對於0<=i<=num,返回一個list,表明i的二進制表示中1的數量.

只有0對應的二進制的1的數量是0,對於任意的正整數num,均可以寫成num = 2**i + k(k<num/2)的形式,若是k=0時對應的1的數量爲1,不然就是1+dp[k].由於k<2**i,因此咱們能夠確保dp[k]必定已經存過數字.

class Solution:
    def countBits(self, num):
        """
        :type num: int
        :rtype: List[int]
        """
        dp = [0] * (num+1)

        carry = 1
        for i in range(1, num + 1):
            if carry*2 == i:
                carry = i
            dp[i] = 1+dp[i-carry]

        return dp
Counting Bits

 

---343.Integer Break

給定一個正整數n,將它拆分紅至少兩個數字的和,使得這些數字之積最大.

我想到的是dp的作法,dp[n]爲n對應的最大積,那麼dp[2]=1,dp[n]=max(i*dp[n-i],i*(n-i))

class Solution:
    def integerBreak(self, n):
        """
        :type n: int
        :rtype: int
        """
        dp = [0]*(n+1)
        dp[0] = 1
        dp[1] = 1
        for i in range(n+1):
            for j in range(i):
                dp[i] = max(dp[i], j*(i-j), j*dp[i-j])

        return dp[-1]
Integer Break

實際上這題經過數學推導,能夠發現最好的就是將數字三等分,若是不行就二等分,這樣就能夠很快求解了.

 

Tree

---94.Binary Tree Inorder Traversal

給定一棵二叉樹,返回它的中序遍歷結果.

遞歸,若是root爲空則返回,不然遞歸遍歷左結點,存入根結點,遞歸遍歷右結點.

若是不用遞歸的話,能夠採用棧來實現,也就是結點非空時就將根結點存入棧,而後進入左結點,直到結點爲空時,從棧中彈出第一個結點加入res[],而後訪問該結點的右結點.

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


class Solution:
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        node = []
        def it(root):
            if root == None:
                return
            else:
                it(root.left)
                node.append(root.val)
                it(root.right)
        it(root)
        return node
Binary Tree Inorder Traversal

 

---100.Same Tree

給定兩棵二叉樹,判斷它們是否相同.

遞歸,若是p與q都存在的話,返回對p與q的val是否相等的判斷結果and對p.left和q.left的判斷結果and對p.right和q.right的判斷結果.若是p與q不存在的話,則用p==q判斷是否二者都爲None.這裏用到的技巧是True and False = Flase.

這題也能夠用棧來實現.

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

class Solution:
    def isSameTree(self, p, q):
        """
        :type p: TreeNode
        :type q: TreeNode
        :rtype: bool
        """
        if p and q:
            return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
        else:
            return p == q
Same Tree

 

---103.Binary Tree Zigzag Level Order Traversal

給定一棵二叉樹,返回它的zigzag遍歷結果.(也就是同一層從左到右,下一層再從右到左,如此循環)

個人方法是設立標誌位i表明第i層,若是結點存在,且res數組的長度小於i,就在res數組中加入一個[],而後將這個結點的值存入,並遞歸左結點和i+1,而後遞歸右結點和i+1.最後再將res中的偶數list作reverse操做.

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

class Solution:
    def zigzagLevelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        res = []
        def helper(root, i):
            if root:
                if len(res) < i:
                    res.append([])
                res[i-1].append(root.val)
                helper(root.left, i+1)
                helper(root.right, i+1)
        
        helper(root,1)
        for i in range(len(res)):
            if i % 2 != 0:
                res[i].reverse()
        return res
            
        
Binary Tree Zigzag Level Order Traversal

 

---107.Binary Tree Level Order Traversal II

給定一棵二叉樹,返回它自底向上,從左到右的遍歷結果.

與103題相似,只不過最後是對整個res作reverse操做.

若是不用遞歸的話,還能夠用dfs+棧或bfs+隊列.

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

class Solution:
    def levelOrderBottom(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        res = []
        def helper(root, i):
            if root:
                if len(res) < i:
                    res.append([])
                res[i-1].append(root.val)
                helper(root.left, i+1)
                helper(root.right, i+1)
        
        helper(root,1)
        res.reverse()
        return res
Binary Tree Level Order Traversal II

 

---110.Balanced Binary Tree

 給定一棵二叉樹,判斷它是否是一棵平衡二叉樹.

平衡二叉樹的定義:要麼是一棵空樹,要麼左右子樹都是平衡二叉樹,而且左右子樹的深度之差的絕對值不超過1.

若是採用求深度的方法,那麼部分結點會被重複訪問不少次,因此想到了後序遍歷,它的特色是訪問到根結點時,根結點對應的左結點和右結點都已經被訪問過了.若是在訪問過程當中發現左結點和右結點的深度之差大於1,就返回-1,同理若是左結點和右結點的返回值已是-1了,也返回-1,否則就返回1+左結點和右結點的較大值.

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

class Solution:
    def isBalanced(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        
        def helper(root):
            if not root:
                return 0
            left = helper(root.left)
            right = helper(root.right)
            if left == -1 or right == -1 or abs(left-right) > 1:
                return -1
            return 1 + max(left, right)
        
        return helper(root) != -1
Balanced Binary Tree

 

---111.Minimum Depth of Binary Tree

給定一棵二叉樹,返回它的最小深度

遞歸解決,對於一棵二叉樹的每個結點,若是它同時有左右子樹,那麼深度爲1+min(left,right),不然深度爲另外一個子樹的最小深度+1.

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

class Solution:
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        
        if not root:
            return 0
        
        if not root.left:
            return 1 + self.minDepth(root.right)
        elif not root.right:
            return 1 + self.minDepth(root.left)
        else:
            return 1 + min(self.minDepth(root.left), self.minDepth(root.right))

        
Minimum Depth of Binary Tree

 

---112.Path Sum

給定一棵二叉樹和一個sum,判斷二叉樹中是否有一條從根結點到葉子結點的路徑,使得結點之和等於sum.

比較簡單,使用一個輔助值tmp記錄路徑的和,若是爲葉子結點且路徑和加上值等於sum則返回True,不然返回helper(root.left) or helper(root.right)

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

class Solution:
    def hasPathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: bool
        """
        
        def helper(root, sum, tmp):
            if not root:
                return False
            tmp += root.val
            if not root.left and not root.right and tmp == sum:
                return True
            else:
                return helper(root.left, sum, tmp) or helper(root.right, sum, tmp)
            
        return helper(root, sum, 0)
Path Sum

 

---113.Path Sum II

給定一棵二叉樹和一個sum,找出全部知足和等於sum的根結點到葉子結點的路徑.

思路和112題大致一致,只不過須要在函數中加入兩個list參數,一個存儲路徑,最後若是判斷等於sum就加入到另外一箇中做爲最後結果.

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

class Solution:
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: List[List[int]]
        """
    
        def dfs(root, sum, ls, res):
            if not root.left and not root.right and sum == root.val:
                ls.append(root.val)
                res.append(ls)
            if root.left:
                dfs(root.left, sum-root.val, ls+[root.val], res)
            if root.right:
                dfs(root.right, sum-root.val, ls+[root.val], res)
                
        if not root:
            return []
        res = []
        dfs(root, sum, [], res)
        return res
Path Sum II

 

---114.Flatten Binary Tree to Linked List

給定一棵二叉樹,將它變爲鏈表,要求in-place操做

在對根結點操做時,若是已經將它的左右子樹都拉平過,就將左子樹加入到根結點和右子樹中間,因此採用後序遍歷順序來遞歸.

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

class Solution:
    def flatten(self, root):
        if not root:
            return
        if root.left:
            self.flatten(root.left)
        if root.right:
            self.flatten(root.right)
        left = root.left
        right = root.left
        while right and right.right:
            right = right.right
 
        if right:
            right.right = root.right
        if left:
            root.right = left
        root.left = None
Flatten Binary Tree to Linked List

 

---129.Sum Root to Leaf Numbers

給定一棵二叉樹,每個結點都是0-9中的一位數字,求全部根結點到葉子結點的路徑上的數字之和.

遞歸,每深刻一個結點就讓當前的值*10傳下去,直到葉子結點後將值存入一個list,最後對該ist求和便可.

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

class Solution:
    def sumNumbers(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
    
        def helper(root, value, res):
            if root:
                helper(root.left, root.val+value*10, res)
                helper(root.right, root.val+value*10, res)
                if not root.left and not root.right:
                    res.append(root.val+value*10)
        
        if not root:
            return 0
        else:
            res = []
            helper(root, 0, res)
            return sum(res)
129.Sum Root to Leaf Numbers

 

---144.Binary Tree Preorder Traversal

給定一棵二叉樹,返回前序遍歷

遞歸的方法很是簡單,這裏用棧的方法,建立兩個list,pre用於保存最後的結果,stack用於保存過程當中的結點.若是棧裏還有結點,首先將這個結點出棧,存入pre,而後將這個結點的右結點和左結點存入棧中.

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

class Solution:
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        pre = []
        stack = [root]
        while stack:
            node = stack.pop()
            if node:
                pre.append(node.val)
                stack.append(node.right)
                stack.append(node.left)
        return pre
144. Binary Tree Preorder Traversal(棧)
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        def helper(root, prelist):
            if root:
                prelist.append(root.val)
                helper(root.left, prelist)
                helper(root.right, prelist)
            
        prelist = []
        helper(root, prelist)
        return prelist
            
144. Binary Tree Preorder Traversal(遞歸)

 

---199. Binary Tree Right Side View

給定一棵二叉樹,想象你站在這顆二叉樹的右邊,從上到下給出你能在這棵樹上看到的值.

定義一個數組view和一個輔助函數,它的功能是從右到左遍歷這顆樹,而且當遍歷到的結點深度等於當前view的長度時,代表這是該層最右邊的結點,將它加入view數組,而後遍歷這個結點的右子結點和左子結點.

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

class Solution:
    def rightSideView(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        
        def helper(root, depth):
            if root:
                if depth == len(view):
                    view.append(root.val)
                helper(root.right, depth+1)
                helper(root.left, depth+1)
                
        view = []
        helper(root, 0)
        return view
                
            
        
199. Binary Tree Right Side View

 

---222. Count Complete Tree Nodes

給定一棵徹底二叉樹,求結點數

首先定義一個輔助函數get_depth用於求一顆徹底二叉樹的深度,而後開始構造主函數.若是不存在結點則返回0,不然分別求當前結點的左子樹深度和右子樹深度.若是左子樹深度等於右子樹深度,說明左子樹是滿二叉樹,那麼只需用深度求出左子樹的結點數,而後再對右子樹求結點數便可.若是左子樹深度不等於右子樹深度,那麼說明右子樹是滿二叉樹,同理.

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

class Solution:
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        
        def get_depth(root):
            depth = 0
            while root:
                root = root.left
                depth += 1
            return depth
        depth = get_depth(root)
        
        if not root:
            return 0
        left_depth = get_depth(root.left)
        right_depth = get_depth(root.right)
        if left_depth == right_depth:
            return pow(2, left_depth) + self.countNodes(root.right)
        else:
            return pow(2, right_depth) + self.countNodes(root.left)
222. Count Complete Tree Nodes

 

---226.Invert Binary Tree

翻轉二叉樹

很簡單的一道題.

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

class Solution:
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        if root:
            tmp = root.right
            root.right = root.left
            root.left = tmp
            self.invertTree(root.left)
            self.invertTree(root.right)
        return root
226. Invert Binary Tree

 

---337.House Robber III

給定一棵二叉樹,其中結點的值表明財產,小偷不能偷兩個相連的結點,求小偷能偷到的最大財產價值.

這種要維護狀態的題首先想到遞歸,用一個大小爲2的一維數組res,res[0]表示不包含當前結點的最大值,res[1]表示包含當前結點的最大值.開始遞歸,若是該結點不存在則返回[0,0],不然left_val等於左結點的遞歸調用,right_val等於右結點的遞歸調用,注意這兩個val實際上都是一個和res大小相同的數組.不包含該結點的話,res[0]=max(left_val)+max(right_val),包含該結點的話,res[1]=root.val+left_val[0]+right_val[0].

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

class Solution:
    def rob(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        def helper(root):
            if not root:
                return [0,0]
            else:
                left_val = helper(root.left)
                right_val = helper(root.right)
                res = [0,0]
                res[0] = max(left_val) + max(right_val)
                res[1] = root.val + left_val[0] + right_val[0]
                return res

        return max(helper(root))
337. House Robber III

 

Hash Table

---187.Repeated DNA Sequences

DNA是由A,C,G,T四種核苷酸構成的,設計一種算法,可以找到一個DNA裏全部重複出現過的長度爲10的核苷酸序列.

使用python的dict構造哈希表,用i遍歷DNA序列s的第一位到倒數第十位,s[i:i+10]就能夠遍歷其中全部長度爲10的序列.若是在dict中存在這個序列且值等於1(表明出現次數),就將它加入到output的list中,且將值加1.不然將該序列加入dict中,且令值等於1.

class Solution:
    def findRepeatedDnaSequences(self, s):
        """
        :type s: str
        :rtype: List[str]
        """
        sub = {}
        output = []
        for i in range(len(s)-9):
            temp = s[i:i+10]
            if temp in sub:
                if sub[temp] == 1:
                    sub[temp] += 1
                    output.append(temp)
            else:
                sub[temp] = 1
                
        return output
187. Repeated DNA Sequences

 

---205. Isomorphic Strings

給定兩個字符串s和t,判斷它們是否是同構的.同構是指,將其中一個字符串中的相同字符用另外一個字符替換,若是這個字符串能夠變爲另外一個字符串,則稱他們是同構的.

這題個人思路是分別遍歷s和t,用兩個dict存儲結果.若是其中已經有了遍歷到的字符,就令值加1,不然添加該字符,而後用dict.values()進行比較便可.可是提交後出現了錯誤.思考之後發現dict內部存放的順序和key放入的順序沒有關係,由於它是採用哈希表的原理.

正確思路是隻用一個dict,鍵爲s的字母,值爲t相同位置的字母,若是s中的字母已經在dict中了,則判斷對應的鍵是否與此時t中的字母相等,若是不相等則false.若是s中的字母不在dict中,判斷此時t中的字母是否在dict中有值相等,若是有則返回false,不然將該鍵值對存入dict.

class Solution:
    def isIsomorphic(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if len(s) != len(t):
            return False
        hashmap = {}
        for i in range(len(s)):
            if s[i] in hashmap:
                if hashmap[s[i]] != t[i]:
                    return False
            else:
                if t[i] in hashmap.values():
                    return False
                else:
                    hashmap[s[i]] = t[i]
        return True
205. Isomorphic Strings

 

---274.H-Index

給定一個非負數組,表明一位科學家的引用因子,求出這位科學家的H-Index.H-index是指他至多有h篇論文分別被引用了至少h次.

計算H-index的方法是將引用因子降序排好,而後找到第一個比引用因子大的序號,將序號-1就是H-index.

class Solution:
    def hIndex(self, citations):
        """
        :type citations: List[int]
        :rtype: int
        """
        if citations == []:
            return 0
        citations.sort(reverse=True)
        for i in range(len(citations)):
            if i + 1 > citations[i]:
                return i

        return len(citations)
274. H-Index

 

---299.Bulls and Cows

一個猜數字的遊戲,給定目標數secret和猜想數guess,猜想數中和目標數大小相同且位置相同的叫bulls,大小相同但位置不一樣的叫cows,要求給出bulls和cows的數量.

首先用map將secret和guess變爲數字list,另外定義兩個長度爲10的list,而後同時遍歷這兩個list,若是數字相同則bulls+1,不然在對應的list的對應位置+1.遍歷結束後比較list每一個位置的較小者,相加就獲得cows的數量.

class Solution:
    def getHint(self, secret, guess):
        """
        :type secret: str
        :type guess: str
        :rtype: str
        """
        nums1 = list(map(int, secret))
        nums2 = list(map(int, guess))
        bulls = 0
        cows = 0
        l1 = [0]*10
        l2 = [0]*10

        for i in range(len(nums1)):
            if nums1[i] == nums2[i]:
                bulls += 1
            else:
                l1[nums1[i]] += 1
                l2[nums2[i]] += 1

        for i in range(10):
            cows += min(l1[i], l2[i])
            
        return str(bulls)+'A'+str(cows)+'B'
299. Bulls and Cows

 

 Depth-first Search

---117.Populating Next Right Pointers in Each Node ||

給定一棵二叉樹,將每一個結點的next結點設爲它右邊的相鄰結點,若是不存在這樣的結點則設爲NULL.

首先創建一個tali結點和一個head結點,其中head結點用於保存tail結點最初的位置.而後遍歷當前root,首先將tail.next指向root.left,若是存在則將tail移動至tail.next,而後將tail.next指向root.right,若是存在則將tail移動至tali.next.遍歷完之後將root指向root.next(由於root比tail高一層,因此root層的next結構已經固定了).若是root存在則重複上述過程,不然將tail指向一開始的head結點,將root指向head的next,即將root下移了一層.

# Definition for binary tree with next pointer.
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None

class Solution:
    # @param root, a tree link node
    # @return nothing
    def connect(self, root):
        tail = head = TreeLinkNode(0)
        while root:
            tail.next = root.left
            if tail.next:
                tail = tail.next
            tail.next = root.right
            if tail.next:
                tail = tail.next
            root = root.next
            if not root:
                tail = head
                root = head.next
117. Populating Next Right Pointers in Each Node II

 

---200.Number of Islands

給定一個二維網格,其中'1'表明陸地,'0'表明水.島是指一塊被水包圍的豎直方向和水平方向相連的陸地.假設網格的四周都是水,求其中島的數量.

經典的DFS思想,遍歷網格,若是當前位置是1就調用dfs函數.在dfs中首先進行邊界判斷,而後若是當前位置是'1'則改成'#',以後對位置的先後左右位置調用dfs函數.

class Solution:
    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        if not grid:
            return 0

        count = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if grid[i][j] == '1':
                    self.dfs(grid, i, j)
                    count += 1
        return count

    def dfs(self, grid, i, j):
        if i<0 or j<0 or i>=len(grid) or j>=len(grid[0]) or grid[i][j] != '1':
            return
        grid[i][j] = '#'
        self.dfs(grid, i+1, j)
        self.dfs(grid, i-1, j)
        self.dfs(grid, i, j+1)
        self.dfs(grid, i, j-1)
200. Number of Islands

 

---98.Validate Binary Search Tree

給定一棵二叉樹,判斷它是否是一棵二叉查找樹(左子樹的全部結點都比該結點小,右子樹的全部結點都比該結點大,且左右子樹都是二叉查找樹).

 

 

還沒有分類

---1.Two Sum

在列表中找到兩個數,使得它們的和等於某一給定值,返回這兩個數的位置.時間複雜度:O(n),python中的字典其實就是哈希表的應用,因此咱們經過字典用哈希表來下降查找的時間複雜度

class Solution:
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        d = {}
        for i, n in enumerate(nums):
            m = target - n
            if m in d:
                return [d[m], i]
            else:
                d[n] = i
Two Sum

 

---2.Add Two Numbers

將兩個倒序存放在單鏈表裏的數相加,將結果倒序存儲在單鏈表裏返回.思路很是簡單,先將兩個單鏈表中的數字分別提取出來求和,而後將=求得的和存入一個單鏈表,實際上相加這一步也能夠直接在原鏈表中完成,只須要添加判斷條件while(l1 or l2 or carry)便可.

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        node1 = l1
        node2 = l2
        l3 = ListNode(0)
        l3.next = ListNode(0)#[0],[0]的特殊狀況
        node3 = l3
        
        sum1 = 0
        coe = 1
        while not node1 is None:
            sum1 += node1.val * coe
            coe *= 10
            node1 = node1.next
        
        sum2 = 0
        coe =1
        while not node2 is None:
            sum2 += node2.val * coe
            coe *= 10
            node2 = node2.next
        
        sum = sum1 + sum2
        
        while sum > 0:
            node3.next = ListNode(sum % 10)
            node3 = node3.next
            sum //= 10
            
        return l3.next    
Add Two Numbers

 

---3.Longest Substring Without Repeating Characters

找到字符串中沒有重複字符的最大子串.一開始沒有想到用字典,而是直接用str來存儲字串,時間複雜度是O(n^2),後來用字典將時間複雜度降到了O(n).注意到僅當字典中出現重複值且該重複值在strat區段裏時才移動start.另外用了Sliding Window的思想,每次將strat移動到重複值的下一位置.

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        start = 0
        max_length = 0
        substring = {}
        for i, c in enumerate(s):
            if c in substring and start <= substring[c]:#只有當重複值是在start後面出現時才移動start
                start = substring[c] + 1#Slding Window的思想
            else:
                max_length = max(max_length, i - start + 1)
            substring[c] = i
            
        return max_length
Longest Substring Without Repeating Characters

 

---5.Longest Palindromic Substring

最長迴文子串問題,一開始個人思路以下:迴文子串的特色是首尾字母相同,因此我對每個字母都找到位於它後面的相同字母,利用切片判斷這一段是否爲迴文子串(str[i:j]==str[i:j][::-1]).雖然AC了可是時間複雜度很高,主要是由於str.find操做很是耗時.

後來看了Solution發現這是一道能夠用動態規劃解決的問題,思路是若s是迴文字串,令s'=s加上s左右兩側的兩個字母,若是這兩個字母相同則s'也是迴文字串.重寫代碼以下:

class Solution:
    def longestPalindrome(self, s):
        """
        :type s: str
        :rtype: str
        """
        max = 0
        palindromic = '' if len(s) == 0 else s[0]
        for i in range(len(s)):
            length = 1
            while i - length >=0 and i + length < len(s) and s[i-length] == s[i+length]:
                tmp = s[i-length:i+length+1]
                if len(tmp) > max:
                    max = len(tmp)
                    palindromic = tmp
                length += 1
            length = 1
            while i - length + 1  >=0 and i + length < len(s) and s[i-length+1] == s[i+length]:
                tmp = s[i-length+1:i+length+1]
                if len(tmp) > max:
                    max = len(tmp)
                    palindromic = tmp
                length += 1
        return palindromic
Longest Palindromic Substring

這道題還有經典的Manacher算法,能夠看這篇文章.Discuss裏的算法實如今這裏.

另外在Discuss裏發現了另外一種作法,思路是一段迴文字符串的後面新增了一個字母,若是新字符串還是迴文字符串的話只有兩種可能:形如bb+b,也就是多了一個字母,或形如a(bb)+a,算上原迴文字符串的前一個字母共多了兩個字母.基於這個思路能夠寫出代碼.由於用到了切片,在題例上運行的速度甚至比Manacher算法還快.

 

---6.ZigZag Conversion

一道將字符串作之字形排列的題目.咱們用n表示行數,將排列後獲得的字符串分爲完整豎列和折線兩部分.每一個完整豎列有n個數,每兩個完整豎列之間的折線有n-2列,每列一個數,所以每兩個完整豎列中同一行的數的間隔是n+n-2=2n-2.同時咱們發現,除了第一行和最後一行以外的第i行都有折線,第i行的第一個折線是第2n-i個數.因而能夠遍歷輸出每一行,斷定條件是這一行咱們要輸出的數字是否超出了字符串的長度.

class Solution:
    def convert(self, s, numRows):
        """
        :type s: str
        :type numRows: int
        :rtype: str
        """
        zigzag = ''
        
        if numRows == 1 or numRows == 0 or numRows >= len(s):
            return s

        
        
        space = 2 * numRows - 2
        for i in range(1,numRows+1):
            n = 0
            if i == 1 or i == numRows:
                while i + n * space <= len(s):
                    zigzag += s[i+n*space-1]
                    n += 1
            else:
                while i + n * space <= len(s):
                    zigzag += s[i+n*space-1]
                    if (2 * numRows - i) + (n * space) <= len(s):
                        zigzag += s[(2*numRows-i)+(n*space)-1]
                    n += 1
        
        return zigzag

ZigZag Conversion
ZigZag Conversion

 

---7.Reverse Integer

將給定的數字倒序輸出.很是簡單的一道題

class Solution(object):
    def reverse(self, x):
        """
        :type x: int
        :rtype: int
        """
        tmp = abs(x)
        
        sum = 0
        while tmp > 0:
            sum = sum * 10 + tmp % 10
            tmp = tmp // 10

        sum = sum if x >= 0 else -sum

        return sum if sum < 2**31 and sum > -2**31 else 0
 
Reverse Integer

 

---8.String to Integer(atoi)

將給定字符串中符合條件的一串數字字符轉化爲int類型返回.個人思路是設定標誌位start=0和符號位sign,遍歷字符串,當start=0時遇到空格則continue,遇到+則記錄sign=1,遇到-則記錄sign=-1,遇到數字則記錄數字;當strat=1時表明已經找到了第一個數字或符號位,此時遇到除數字以外的字符都break,遇到數字則繼續記錄數字.注意咱們獲得的整數值不能超過INT_MAX和INT_MIN.後來發現其實用str.strip()函數來去除字符串頭尾的空格會更方便.

class Solution(object):
    def myAtoi(self, str):
        """
        :type str: str
        :rtype: int
        """
        ans = 0
        start = 0
        sign = 0
        if str.isspace() is True:
            print(0)
        for i in str:
            if start == 0:
                if i.isspace() is True:
                    continue
                if i == '+':
                    sign = 1
                elif i == '-':
                    sign = -1
                elif i.isdigit() is True:
                    sign = 1
                    ans = ans * 10 + int(i)
                else:
                    break
                start = 1
            else:
                if i.isdigit() is True:
                    ans = ans * 10 + int(i)
                else:
                    break

        ans = sign * ans
        if ans >= 2147483647:
            return 2147483647
        elif ans <= -2147483648:
            return -2147483648
        else:
            return ans
String to Integer(atoi)

 

---9.Palindrome Number

判斷一個數字是不是迴文數.題目要求不能用額外的空間,不然能夠利用python的字符串切片輕鬆解決.個人思路是求出該整數的位數,判斷第一位數和最後一位數是否相同,若是相同則將位數/100,而後將原數字的首尾兩個數刪除,最後若是位數<1說明是迴文數.

class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if x < 0:
            return False
        
        high = 1
        while x / high >= 10:
            high *= 10

        while x // high == x % 10:
            x = x % high // 10
            high /= 100
            if high < 1:
                return True
            
        return False
Palindrome Number

 

---12.Integer to Roman

將十進制數字轉化爲羅馬數字.比較簡單的一道題.個人思路是判斷當前位數,改變表明1/5/10的字符而後逐位輸出.也能夠直接將每位上的各類字符表示存在列表裏,而後直接取出.

class Solution(object):
    def intToRoman(self, num):
        """
        :type num: int
        :rtype: str
        """
        carry = 1
        roman = ''

        while num != 0:
            n = num % 10
            num //= 10
            if carry == 1:
                numeral_1 = 'I'
                numeral_5 = 'V'
                numeral_10 = 'X'
            elif carry == 10:
                numeral_1 = 'X'
                numeral_5 = 'L'
                numeral_10 = 'C'
            elif carry == 100:
                numeral_1 = 'C'
                numeral_5 = 'D'
                numeral_10 = 'M'
            else:
                numeral_1 = 'M'
                numeral_5 = ''
                numeral_10 = ''

            if 1 <= n <= 3:
                roman = numeral_1 * n + roman
            elif n == 4:
                roman = numeral_1 + numeral_5 + roman
            elif 5 <= n <= 8:
                roman = numeral_5 + numeral_1 * (n - 5) + roman
            elif n == 9:
                roman = numeral_1 + numeral_10 + roman

            carry *= 10

        return roman
Integer to Roman

 

---13.Roman to Integer

將羅馬數字轉化爲十進制數字.很是無聊的一道題.比較簡單的方法是寫很是多的if語句來判斷,或者將羅馬數字與對應的十進制數字存入字典來轉換.下面是我在discuss裏看到的一個方案,巧妙利用了羅馬數字"大數前面的小數用來減,大數後面的小數用來加"這個特色.

class Solution(object):
    def romanToInt(self, s):
        """
        :type s: str
        :rtype: int
        """
        roman_map = {
            "I": 1,
            "V": 5,
            "X": 10,
            "L": 50,
            "C": 100,
            "D": 500,
            "M": 1000,
        }
        result = 0
        last_num = None
        for char in s:
            current_num = roman_map[char]
            if last_num is None or last_num >= current_num:
                result += current_num
            elif last_num < current_num:
                result += current_num - 2 * last_num
            last_num = current_num
        return result
            
Roman to Integer

 

---14.Longest Common Prefix

找最長公共前綴字符串.個人思路是找出列表中最短的字符串,而後對最短字符串的每一個字符都在列表中遍歷,直到出現不一樣或者遍歷結束爲止.在discuss裏看到不少方法利用了python中的sort(),min(),max()這些內置方法對字符串排序,會使時間快不少.

class Solution(object):
    def longestCommonPrefix(self, strs):
        """
        :type strs: List[str]
        :rtype: str
        """
        prefix = ''
        
        if strs == []:
            return prefix
    
        minimum = float("inf")
        for s in strs:
            minimum = min(len(s), minimum)
            
        i = 0
        for j in range(minimum):
            for i in range(len(strs)):
                while strs[i][j] != strs[0][j]:
                    return prefix
            prefix = prefix + strs[0][j]
        
        return prefix
Longest Common Prefix

 

---15.3Sum

給定一個數組,找到其中三個數的和爲零的全部可能,以列表形式返回.這道題的基本思路是先將數組排序,從左往右遍歷一次.在遍歷每一個數的過程當中設立兩個指針,若是三個數的和大於零則左移右指針,若是三個數的和小於零則右移左指針,直到兩個指針相遇.注意咱們用的是set()來存儲找到的結果,能夠避免list中出現重複.在此基礎上,我增長了一個對排序過的數組的操做,即當最左邊兩個數與最右邊一個數的和大於零時刪去最右邊的數,當最左邊一個數與最右邊兩個數的和小於零時刪去最左邊的數.這個操做大大提高了運行速度.

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        zeros = set()
        nums.sort()
        if len(nums) < 3:
            return []

        if nums.count(0) > len(nums)-2:
            return [[0, 0, 0]]
        
        while len(nums) > 3 and (nums[0]+nums[1]+nums[-1] > 0 or nums[-1]+nums[-2]+nums[0] < 0):
            if nums[0] + nums[1] + nums[-1] > 0:
                nums.remove(nums[-1])
            else:
                nums.remove(nums[0])
        
        for i in range(len(nums)-2):
            if nums[i] > 0:
                break
            j = i + 1
            k = len(nums) - 1
            while j < k:
                sum = nums[i] + nums[j] + nums[k]
                if sum == 0:
                    zeros.add((nums[i], nums[j], nums[k]))
                    j += 1
                    continue
                elif sum < 0:
                    j += 1
                else:
                    k -= 1

        return list(map(list,zeros))
3Sum
相關文章
相關標籤/搜索