1 - 從strStr談面試技巧與代碼風格
13.字符串查找
如果target在source中,返回起始下標,否則返回-1
要點:該題O(mn)可過,兩層循環即可。
class Solution: def strStr(self, source, target): # write your code here if source is None or target is None: return -1 if target == '': return 0 for i in range(len(source)): m = i n = 0 while m < len(source) and source[m] == target[n]: if n == len(target) - 1: return i m += 1 n += 1 return -1
17.4.7二刷
class Solution: def strStr(self, source, target): # write your code here if source is None or target is None: return -1 if not target: return 0 for i in range(len(source) - len(target) + 1): for j in range(len(target)): if source[i + j] != target[j]: break if j == len(target) - 1: return i return -1
-------------------------------------------------------------------------
17.子集
返回一個整數list的所有子集。
要點:某些地方注意使用[:]做拷貝。
class Solution: """ @param S: The set of numbers. @return: A list of lists. See example. """ def subsets(self, S): # write your code here results = [] if not S: return results S.sort() self.dfsHelper(S, 0, [], results) return results def dfsHelper(self, S, startnum, subset, results): results.append(subset[:]) for i in range(startnum, len(S)): subset.append(S[i]) self.dfsHelper(S, i + 1, subset, results) subset.pop()
17.4.7二刷
class Solution: """ @param S: The set of numbers. @return: A list of lists. See example. """ def subsets(self, S): # write your code here result = [] S.sort() self.helper(S, 0, [], result) return result def helper(self, S, start, subset, result): result.append(subset[:]) for i in range(start, len(S)): subset.append(S[i]) self.helper(S, i + 1, subset, result) subset.pop()
-------------------------------------------------------------------------
18.帶重復元素的子集
給定一個可能具有重復數字的列表,返回其所有可能的子集(子集不能重復)。
要點:選代表,當存在重復元素時,必須前一個元素在子集中,后一個元素才能加入子集。
class Solution: """ @param S: A set of numbers. @return: A list of lists. All valid subsets. """ def subsetsWithDup(self, S): # write your code here results = [] if not S: return results S.sort() self.dfsHelper(S, 0, [], results) return results def dfsHelper(self, S, start_index, subset, results): results.append(subset[:]) for i in range(start_index, len(S)): if i != start_index and subset.count(S[i]) != i - S.index(S[i]): continue subset.append(S[i]) self.dfsHelper(S, i + 1, subset, results) subset.pop()
17.4.7二刷
class Solution: """ @param S: A set of numbers. @return: A list of lists. All valid subsets. """ def subsetsWithDup(self, S): # write your code here results = [] S.sort() self.helper(S, 0, [], results) return results def helper(self, S, start_index, subset, results): results.append(subset[:]) for i in range(start_index, len(S)): # 注意下面這個寫法 if i != start_index and S[i] == S[i - 1]: continue subset.append(S[i]) self.helper(S, i + 1, subset, results) subset.pop()
-------------------------------------------------------------------------
15.全排列
給定一個數字列表,返回其所有可能的排列。沒有重復數字。
要點:要合理使用切片,二刷記得優化
class Solution: """ @param nums: A list of Integers. @return: A list of permutations. """ def permute(self, nums): # write your code here results = [] if nums is None: return results nums.sort() self.dfsHelper(nums[:], [], results, len(nums)) return results def dfsHelper(self, nums, subset, results, length): if len(subset) == length: results.append(subset[:]) return for i in range(len(nums)): subset.append(nums[i]) self.dfsHelper(nums[:i] + nums[i + 1:], subset, results, length) subset.pop()
17.4.7二刷,使用set避免大量切片,set刪除指定元素O(1)
class Solution: """ @param nums: A list of Integers. @return: A list of permutations. """ def permute(self, nums): # write your code here result = [] self.helper(nums, result, [], set(range(len(nums)))) return result def helper(self, nums, result, subsequence, not_visited): if not not_visited: result.append(subsequence[:]) return for index in not_visited: subsequence.append(nums[index]) not_visited.remove(index) self.helper(nums, result, subsequence, not_visited) not_visited.add(index) subsequence.pop()
-------------------------------------------------------------------------
16.帶重復元素的排列
給出一個具有重復數字的列表,找出列表所有不同的排列。
要點:選代表。重復元素中,后面的進入subset的前提是前面的都在subset中。
class Solution: """ @param nums: A list of integers. @return: A list of unique permutations. """ def permuteUnique(self, nums): # write your code here results = [] if nums is None: return results nums.sort() self.dfsHelper(nums[:], [], results, nums) return results def dfsHelper(self, nums, subset, results, S): if len(subset) == len(S): results.append(subset[:]) return for i in range(len(nums)): if nums.count(nums[i]) > 1 and nums.index(nums[i]) != i: continue subset.append(nums[i]) self.dfsHelper(nums[:i] + nums[i + 1:], subset, results, S) subset.pop()
17.4.7二刷
class Solution: """ @param nums: A list of integers. @return: A list of unique permutations. """ def permuteUnique(self, nums): # write your code here result = [] nums.sort() self.helper(nums, result, [], set(range(len(nums)))) return result def helper(self, nums, result, subsequence, not_visited): if not not_visited: result.append(subsequence[:]) return for index in not_visited: if index != 0 and nums[index] == nums[index - 1] \ and (index - 1) in not_visited: continue subsequence.append(nums[index]) not_visited.remove(index) self.helper(nums, result, subsequence, not_visited) not_visited.add(index) subsequence.pop()
-------------------------------------------------------------------------
594.strStr II
如果target在source中,返回起始下標,否則返回-1,要求時間復雜度O(m + n)
要點:使用Rabin Karp,維護hash滑動窗口,計算原串各個子串hash值,然后與目標串hash值比較。
注意1、整形越界。2、減法可能導致負數。3、double check
class Solution: # @param {string} source a source string # @param {string} target a target string # @return {int} an integer as index def strStr2(self, source, target): # Write your code here BASE = 1000000 if source is None or target is None: return -1 if target == '': return 0 power = 1 for i in range(len(target) - 1): power = (power * 31) % BASE targetHashCode = 0 for i in range(len(target)): targetHashCode = (targetHashCode * 31 + ord(target[i])) % BASE sourceHashCode = 0 for i in range(len(source)): if i < len(target): sourceHashCode = (sourceHashCode * 31 + ord(source[i])) % BASE else: toMinus = ord(source[i - len(target)]) * power sourceHashCode = (sourceHashCode - toMinus) % BASE sourceHashCode = (sourceHashCode * 31 + ord(source[i])) % BASE if sourceHashCode < 0: sourceHashCode = (sourceHashCode + BASE) % BASE if i >= len(target) - 1 and sourceHashCode == targetHashCode: n = 0 while source[n + i - len(target) + 1] == target[n]: if n == len(target) - 1: return i - len(target) + 1 n += 1 return -1
17.4.7二刷
class Solution: # @param {string} source a source string # @param {string} target a target string # @return {int} an integer as index def strStr2(self, source, target): # Write your code here BASE = 1000000 if source is None or target is None: return -1 if not target: return 0 m, n = len(source), len(target) # power power = 1 for i in range(n): power = (power * 31) % BASE # target hash code target_code = 0 for i in range(n): target_code = (target_code * 31 + ord(target[i])) % BASE # source hash code source_code = 0 for i in range(m): # abc + d source_code = (source_code * 31 + ord(source[i])) % BASE if i < n - 1: continue # abcd - a if i > n - 1: source_code -= (ord(source[i - n]) * power) % BASE if source_code < 0: source_code += BASE # double check if source_code == target_code: if source[i - n + 1: i + 1] == target: return i - n + 1 return -1
2 - 二分法
459.排序數組中最接近的元素
在一個排好序的數組 A 中找到 i 使得 A[i] 最接近 target(存在重復元素時,可返回任意一個元素的下標)
要點:按九章的二分寫法,left和right在結束時停止在符合判斷條件的分界線處,判斷left和right哪個更接近即可。
class Solution: # @param {int[]} A an integer array sorted in ascending order # @param {int} target an integer # @return {int} an integer def closestNumber(self, A, target): # Write your code here if not A or target is None: return -1 left = 0 right = len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] >= target: right = mid else: left = mid if A[left] == target: return left elif A[right] == target: return right elif abs(A[left] - target) <= abs(A[right] - target): return left else: return right
17.4.8二刷
class Solution: # @param {int[]} A an integer array sorted in ascending order # @param {int} target an integer # @return {int} an integer def closestNumber(self, A, target): # Write your code here if not A or target is None: return -1 left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] < target: left = mid else: right = mid return left if abs(target - A[left]) < abs(target - A[right]) else right
-------------------------------------------------------------------------
458.目標最后位置
給一個升序數組,找到target最后一次出現的位置,如果沒出現過返回-1
要點:OOXX經典問題,關鍵在於==mid時的判斷
class Solution: # @param {int[]} A an integer array sorted in ascending order # @param {int} target an integer # @return {int} an integer def lastPosition(self, A, target): # Write your code here if not A: return -1 left = 0 right = len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] == target: left = mid elif A[mid] < target: left = mid else: right = mid if A[right] == target: return right if A[left] == target: return left return -1
17.4.8二刷
class Solution: # @param {int[]} A an integer array sorted in ascending order # @param {int} target an integer # @return {int} an integer def lastPosition(self, A, target): # Write your code here if not A or target is None: return -1 left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] <= target: left = mid else: right = mid if A[right] == target: return right if A[left] == target: return left return -1
-------------------------------------------------------------------------
28.搜索二維矩陣
寫出一個高效的算法來搜索 m × n矩陣中的值。
這個矩陣具有以下特性:
- 每行中的整數從左到右是排序的。
- 每行的第一個數大於上一行的最后一個整數。
要點:一刷用了兩次二分,二刷可以試試讓元素比較右邊和下邊的元素。
class Solution: """ @param matrix, a list of lists of integers @param target, an integer @return a boolean, indicate whether matrix contains target """ def searchMatrix(self, matrix, target): # write your code here if not matrix: return False m = len(matrix) n = len(matrix[0]) if n == 0: return False left, right = 0, m - 1 while left + 1 < right: mid = (right - left) / 2 + left if matrix[mid][0] < target: left = mid elif matrix[mid][0] > target: right = mid else: return True if matrix[right][0] <= target: row_num = right elif matrix[left][0] <= target: row_num = left elif left - 1 >= 0 and matrix[left][0] <= target: row_num = left - 1 else: return False left, right = 0, n - 1 while left + 1 < right: mid = (right - left) / 2 + left if matrix[row_num][mid] < target: left = mid elif matrix[row_num][mid] > target: right = mid else: return True if matrix[row_num][left] == target or matrix[row_num][right] == target: return True return False
17.4.8二刷
class Solution: """ @param matrix, a list of lists of integers @param target, an integer @return a boolean, indicate whether matrix contains target """ def searchMatrix(self, matrix, target): # write your code here if not matrix or not matrix[0] or target is None: return False row = self.binSearch([a[0] for a in matrix], target) col = self.binSearch(matrix[row], target) if matrix[row][col] == target: return True return False def binSearch(self, A, target): left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] < target: left = mid else: right = mid if A[right] <= target: return right else: return left
-------------------------------------------------------------------------
585.Maximum Number in Mountain Sequence
Given a mountain sequence of n
integers which increase firstly and then decrease, find the mountain top.
要點:mid與左右兩邊比較,確定是上升的還是下降的
class Solution: # @param {int[]} nums a mountain sequence which increase firstly and then decrease # @return {int} then mountain top def mountainSequence(self, nums): # Write your code here if len(nums) == 1: return nums[0] left = 0 right = len(nums) - 1 while left + 1 < right: mid = (right - left) / 2 + left if nums[mid - 1] < nums[mid] and nums[mid] < nums[mid + 1]: left = mid elif nums[mid - 1] > nums[mid] and nums[mid] > nums[mid + 1]: right = mid else: return nums[mid] return nums[left] if nums[left] > nums[right] else nums[right]
17.4.8二刷
class Solution: # @param {int[]} nums a mountain sequence which increase firstly and then decrease # @return {int} then mountain top def mountainSequence(self, nums): # Write your code here left, right = 0, len(nums) - 1 while left + 1 < right: mid = (right - left) / 2 + left if nums[mid - 1] < nums[mid]: left = mid else: right = mid if nums[right] > nums[left]: return nums[right] return nums[left]
-------------------------------------------------------------------------
447.在大數組中查找
給一個按照升序排序的正整數數組。這個數組很大以至於你只能通過固定的接口 ArrayReader.get(k)
來訪問第k個數。並且你也沒有辦法得知這個數組有多大。找到給出的整數target第一次出現的位置。你的算法需要在O(logk)的時間復雜度內完成,k為target第一次出現的位置的下標。如果找不到target,返回-1。
要點:可認為整個數組是無限長,遞增的。使用乘法增加的思想探測index>target的地方。
""" Definition of ArrayReader: class ArrayReader: def get(self, index): # this would return the number on the given index # return -1 if index is less than zero. """ class Solution: # @param {ArrayReader} reader: An instance of ArrayReader # @param {int} target an integer # @return {int} an integer def searchBigSortedArray(self, reader, target): # write your code here if not reader or not target: return -1 index = 0 while reader.get(index) < target: index = 2 * index + 1 left = 0 right = index while left + 1 < right: mid = (right - left) / 2 + left if reader.get(mid) >= target: right = mid else: left = mid if reader.get(left) == target: return left if reader.get(right) == target: return right return -1
17.4.8二刷
""" Definition of ArrayReader: class ArrayReader: def get(self, index): # this would return the number on the given index # return -1 if index is less than zero. """ class Solution: # @param {ArrayReader} reader: An instance of ArrayReader # @param {int} target an integer # @return {int} an integer def searchBigSortedArray(self, reader, target): # write your code here if not reader or target is None: return -1 index = 1 while reader.get(index) <= target: index *= 2 left, right = 0, index while left + 1 < right: mid = (right - left) / 2 + left if reader.get(mid) < target: left = mid else: right = mid if reader.get(left) == target: return left if reader.get(right) == target: return right return -1
-------------------------------------------------------------------------
159.尋找旋轉排序數組的最小值
假設一個旋轉排序的數組其起始位置是未知的(比如0 1 2 4 5 6 7 可能變成是4 5 6 7 0 1 2)。你需要找到其中最小的元素。你可以假設數組中不存在重復的元素。
要點:mid的判斷
class Solution: # @param nums: a rotated sorted array # @return: the minimum number in the array def findMin(self, nums): # write your code here if not nums: return -1 left = 0 right = len(nums) - 1 while left + 1 < right: mid = (right - left) / 2 + left if nums[mid] < nums[right]: right = mid elif nums[mid] > nums[right]: left = mid return nums[left] if nums[left] < nums[right] else nums[right]
17.4.9二刷
class Solution: # @param nums: a rotated sorted array # @return: the minimum number in the array def findMin(self, nums): # write your code here left, right = 0, len(nums) - 1 while left + 1 < right: mid = (right - left) / 2 + left if nums[left] < nums[mid] < nums[right]: return nums[left] elif nums[mid] < nums[right]: right = mid else: left = mid if nums[left] < nums[right]: return nums[left] return nums[right]
-------------------------------------------------------------------------
75.尋找峰值
你給出一個整數數組(size為n),其具有以下特點:
- 相鄰位置的數字是不同的 //數組不存在“平台”
- A[0] < A[1] 並且 A[n - 2] > A[n - 1] //至少存在一個峰
假定P是峰值的位置則滿足A[P] > A[P-1]
且A[P] > A[P+1]
,返回數組中任意一個峰值的位置。
要點:根據mid是上升、下降、峰、谷分開判斷
class Solution: #@param A: An integers list. #@return: return any of peek positions. def findPeak(self, A): # write your code here if not A: return -1 left = 0 right = len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if mid - 1 < 0: left = mid elif mid + 1 >= len(A): right = mid elif A[mid - 1] < A[mid] and A[mid] < A[mid + 1]: left = mid elif A[mid - 1] > A[mid] and A[mid] > A[mid + 1]: right = mid elif A[mid - 1] > A[mid] and A[mid] < A[mid + 1]: left = mid elif A[mid - 1] < A[mid] and A[mid] > A[mid + 1]: return mid if right - 1 >= 0 and right + 1 < len(A) \ and A[right - 1] < A[right] and A[right] > A[right + 1]: return right else: return left
17.4.8二刷
class Solution: #@param A: An integers list. #@return: return any of peek positions. def findPeak(self, A): # write your code here left, right = 0, len(A) - 1 while left - 1 < right: mid = (right - left) / 2 + left if A[mid - 1] < A[mid] < A[mid + 1]: left = mid elif A[mid - 1] > A[mid] > A[mid + 1]: right = mid elif A[mid - 1] > A[mid] < A[mid + 1]: right = mid else: return mid
-------------------------------------------------------------------------
74.第一個錯誤的代碼版本
代碼庫的版本號是從 1 到 n 的整數。某一天,有人提交了錯誤版本的代碼,因此造成自身及之后版本的代碼在單元測試中均出錯。請找出第一個錯誤的版本號。
要點:OOXX型找符合條件的最后一個
#class SVNRepo: # @classmethod # def isBadVersion(cls, id) # # Run unit tests to check whether verison `id` is a bad version # # return true if unit tests passed else false. # You can use SVNRepo.isBadVersion(10) to check whether version 10 is a # bad version. class Solution: """ @param n: An integers. @return: An integer which is the first bad version. """ def findFirstBadVersion(self, n): # write your code here if n == 1: return 1 left = 1 right = n while left + 1 < right: mid = (right - left) / 2 + left if SVNRepo.isBadVersion(mid): right = mid else: left = mid if SVNRepo.isBadVersion(left): return left else: return right
17.4.8二刷
#class SVNRepo: # @classmethod # def isBadVersion(cls, id) # # Run unit tests to check whether verison `id` is a bad version # # return true if unit tests passed else false. # You can use SVNRepo.isBadVersion(10) to check whether version 10 is a # bad version. class Solution: """ @param n: An integers. @return: An integer which is the first bad version. """ def findFirstBadVersion(self, n): # write your code here left, right = 1, n while left + 1 < right: mid = (right - left) / 2 + left if SVNRepo.isBadVersion(mid): right = mid else: left = mid if SVNRepo.isBadVersion(left): return left else: return right
-------------------------------------------------------------------------
62.搜索旋轉排序數組
假設有一個排序的按未知的旋轉軸旋轉的數組(比如,0 1 2 4 5 6 7 可能成為4 5 6 7 0 1 2)。給定一個目標值進行搜索,如果在數組中找到目標值返回數組中的索引位置,否則返回-1。你可以假設數組中不存在重復的元素。
要點:多種情況的判斷
class Solution: """ @param A : a list of integers @param target : an integer to be searched @return : an integer """ def search(self, A, target): # write your code here if not A or target is None: return -1 left = 0 right = len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[right] < target: if A[mid] < A[right]: right = mid elif A[mid] > target: right = mid else: left = mid else: if A[mid] < target: left = mid elif A[mid] > A[right]: left = mid else: right = mid if A[left] == target: return left if A[right] == target: return right return -1
17.4.9二刷
要注意target與left right相等的情況
class Solution: """ @param A : a list of integers @param target : an integer to be searched @return : an integer """ def search(self, A, target): # write your code here if not A or target is None: return -1 left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[left] < A[right]: if A[mid] >= target: right = mid else: left = mid else: if target >= A[left]: if A[left] < A[mid] <= target: left = mid else: right = mid else: if target <= A[mid] < A[right]: right = mid else: left = mid if A[left] == target: return left if A[right] == target: return right return -1
-------------------------------------------------------------------------
600. Smallest Rectangle Enclosing Black Pixels
尋找能套住圖中黑色像素的最小矩形。
要點:四次二分法,二刷要優化一下代碼
class Solution(object): # @param image {List[List[str]]} a binary matrix with '0' and '1' # @param x, y {int} the location of one of the black pixels # @return an integer def minArea(self, image, x, y): # Write your code here m, n = len(image), len(image[0]) left, right = 0, x while left + 1 < right: mid = (right - left) / 2 + left flag = False for i in range(n): if image[mid][i] == '1': flag = True break if not flag: left = mid else: right = mid flag = False for i in range(n): if image[left][i] == '1': flag = True break if not flag: row1 = right else: row1 = left left, right = x, m - 1 while left + 1 < right: mid = (right - left) / 2 + left flag = False for i in range(n): if image[mid][i] == '1': flag = True break if not flag: right = mid else: left = mid flag = False for i in range(n): if image[right][i] == '1': flag = True break if not flag: row2 = left else: row2 = right left, right = 0, y while left + 1 < right: mid = (right - left) / 2 + left flag = False for i in range(m): if image[i][mid] == '1': flag = True break if flag: right = mid else: left = mid flag = False for i in range(m): if image[i][left] == '1': flag = True break if not flag: col1 = right else: col1 = left left, right = y, n - 1 while left + 1 < right: mid = (right - left) / 2 + left flag = False for i in range(m): if image[i][mid] == '1': flag = True break if flag: left = mid else: right = mid flag = False for i in range(m): if image[i][right] == '1': flag = True break if not flag: col2 = left else: col2 = right return (row2 + 1 - row1) * (col2 + 1 - col1)
17.4.9二刷
class Solution(object): # @param image {List[List[str]]} a binary matrix with '0' and '1' # @param x, y {int} the location of one of the black pixels # @return an integer def minArea(self, image, x, y): # Write your code here m, n = len(image) - 1, len(image[0]) - 1 row_left = self.binSearch(image, 0, x, 'row', True) row_right = self.binSearch(image, x, m, 'row', False) col_left = self.binSearch(image, 0, y, 'col', True) col_right = self.binSearch(image, y, n, 'col', False) return (row_right - row_left + 1) * (col_right - col_left + 1) def binSearch(self, image, left, right, type, isFindStart): while left + 1 < right: mid = (right - left) / 2 + left if self.check(image, mid, type, isFindStart): right = mid else: left = mid if self.check(image, left, type, isFindStart): return left if isFindStart else left - 1 if self.check(image, right, type, isFindStart): return right if isFindStart else right - 1 return len(image) - 1 if type == 'row' else len(image[0]) - 1 def check(self, image, index, type, isFindStart): m, n = len(image), len(image[0]) if type == 'row': for i in range(n): if image[index][i] == '1': return False ^ isFindStart return True ^ isFindStart else: for i in range(m): if image[i][index] == '1': return False ^ isFindStart return True ^ isFindStart
-------------------------------------------------------------------------
462.Total Occurrence of Target
Given a target number and an integer array sorted in ascending order. Find the total number of occurrences of target in the array.
class Solution: # @param {int[]} A an integer array sorted in ascending order # @param {int} target an integer # @return {int} an integer def totalOccurrence(self, A, target): # Write your code here if not A or not target: return 0 left1 = 0 right1 = len(A) - 1 while left1 + 1 < right1: mid1 = (right1 - left1) / 2 + left1 if A[mid1] >= target: right1 = mid1 else: left1 = mid1 startIndex = -1 if A[left1] == target: startIndex = left1 elif A[right1] == target: startIndex = right1 if startIndex == -1: return 0 left2 = 0 right2 = len(A) - 1 while left2 + 1 < right2: mid2 = (right2 - left2) / 2 + left2 if A[mid2] <= target: left2 = mid2 else: right2 = mid2 endIndex = -1 if A[right2] == target: endIndex = right2 elif A[left2] == target: endIndex = left2 if endIndex == -1: return 0 return endIndex - startIndex + 1
17.4.9二刷
class Solution: # @param {int[]} A an integer array sorted in ascending order # @param {int} target an integer # @return {int} an integer def totalOccurrence(self, A, target): # Write your code here if not A or target is None: return 0 left = self.binSearch(A, target, True) right = self.binSearch(A, target, False) if left == -1: return 0 return right - left + 1 def binSearch(self, A, target, isFirst): left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if isFirst and A[mid] < target: left = mid elif (not isFirst) and A[mid] <= target: left = mid else: right = mid if isFirst: if A[left] == target: return left if A[right] == target: return right else: if A[right] == target: return right if A[left] == target: return left return -1
-------------------------------------------------------------------------
254.Drop Eggs
經典的丟雞蛋問題
class Solution: # @param {int} n an integer # @return {int} an integer def dropEggs(self, n): # Write your code here if not n: return 0 left = 1 right = n while left + 1 < right: mid = (right - left) / 2 + left temp = 0.5 * mid ** 2 + 0.5 * mid - n + 1 if temp >= 0: right = mid elif temp < 0: left = mid return left if (0.5 * left ** 2 + 0.5 * left - n + 1) > 0 else right
17.4.9二刷
class Solution: # @param {int} n an integer # @return {int} an integer def dropEggs(self, n): # Write your code here if not n: return 0 left, right = 1, n while left + 1 < right: mid = (right - left) / 2 + left if (1 + mid) * mid / 2 >= n: right = mid else: left = mid if (1 + left) * left / 2 >= n: return left return right
-------------------------------------------------------------------------
14.First Position of Target
find first X in OOXX
class Solution: # @param nums: The integer array # @param target: Target number to find # @return the first position of target in nums, position start from 0 def binarySearch(self, nums, target): # write your code here if not nums: return -1 left = 0 right = len(nums) - 1 while left + 1 < right: mid = (right - left) / 2 + left if nums[mid] >= target: right = mid else: left = mid if nums[left] == target: return left if nums[right] == target: return right return -1
17.4.9二刷
class Solution: # @param nums: The integer array # @param target: Target number to find # @return the first position of target in nums, position start from 0 def binarySearch(self, nums, target): # write your code here if not nums or target is None: return -1 left, right = 0, len(nums) - 1 while left + 1 < right: mid = (right - left) / 2 + left if nums[mid] < target: left = mid else: right = mid for index in (left, right): if nums[index] == target: return index return -1
-------------------------------------------------------------------------
460.K Closest Numbers In Sorted Array
find k closest numbers to target in A. A is in ascending order.
class Solution: # @param {int[]} A an integer array # @param {int} target an integer # @param {int} k a non-negative integer # @return {int[]} an integer array def kClosestNumbers(self, A, target, k): # Write your code here result = [] left = 0 right = len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] >= target: right = mid else: left = mid while len(result) < k: if left >= 0 and right <= len(A) - 1: if abs(A[left] - target) <= abs(A[right] - target): result.append(A[left]) left -= 1 else: result.append(A[right]) right += 1 elif left >= 0: result.append(A[left]) left -= 1 else: result.append(A[right]) right += 1 return result
17.4.9二刷
class Solution: # @param {int[]} A an integer array # @param {int} target an integer # @param {int} k a non-negative integer # @return {int[]} an integer array def kClosestNumbers(self, A, target, k): # Write your code here left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] < target: left = mid else: right = mid result = [] while len(result) < k: while len(result) < k and left >= 0 and right < len(A): if abs(target - A[left]) <= abs(target - A[right]): result.append(A[left]) left -= 1 else: result.append(A[right]) right += 1 while len(result) < k and left >= 0: result.append(A[left]) left -= 1 while len(result) < k and right >= 0: result.append(A[right]) right += 1 return result
-------------------------------------------------------------------------
414.Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
class Solution(object): def divide(self, dividend, divisor): INT_MAX = 2147483647 if divisor == 0: return INT_MAX neg = dividend > 0 and divisor < 0 or dividend < 0 and divisor > 0 a, b = abs(dividend), abs(divisor) ans, shift = 0, 31 while shift >= 0: if a >= b << shift: a -= b << shift ans += 1 << shift shift -= 1 if neg: ans = - ans if ans > INT_MAX: return INT_MAX return ans
-------------------------------------------------------------------------
414.Divide Two Integers
兩數相除,不許用除號和取余,注意上下溢出。
位運算 >>, <<
17.4.10二刷
class Solution: # @param {int} dividend the dividend # @param {int} divisor the divisor # @return {int} the result def divide(self, dividend, divisor): # Write your code here INT_MAX = 2147483647 if divisor == 0: return INT_MAX if dividend >= 0 else -INT_MAX - 1 neg = dividend >= 0 and divisor < 0 or dividend < 0 and divisor > 0 dividend, divisor = abs(dividend), abs(divisor) ans, shift = 0, 31 while shift >= 0: if dividend >= divisor << shift: dividend -= divisor << shift ans += 1 << shift shift -= 1 if neg: ans = -ans if ans > INT_MAX: ans = INT_MAX if ans < -INT_MAX - 1: ans = -INT_MAX - 1 return ans
-------------------------------------------------------------------------
61.search-for-a-range
Given a sorted array of n integers, find the starting and ending position of a given target value.
class Solution: """ @param A : a list of integers @param target : an integer to be searched @return : a list of length 2, [index1, index2] """ def searchRange(self, A, target): # write your code here if not A or target is None: return [-1, -1] left = 0 right = len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] >= target: right = mid else: left = mid if A[left] == target: leftBound = left elif A[right] == target: leftBound = right else: return [-1, -1] left = 0 right = len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] > target: right = mid else: left = mid if A[right] == target: rightBound = right elif A[left] == target: rightBound = left return [leftBound, rightBound]
17.4.9二刷
class Solution: """ @param A : a list of integers @param target : an integer to be searched @return : a list of length 2, [index1, index2] """ def searchRange(self, A, target): # write your code here if not A or target is None: return [-1, -1] return [self.binSearch(A, target, True), self.binSearch(A, target, False)] def binSearch(self, A, target, isFirst): left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if isFirst and A[mid] < target: left = mid elif (not isFirst) and A[mid] <= target: left = mid else: right = mid if isFirst: if A[left] == target: return left if A[right] == target: return right else: if A[right] == target: return right if A[left] == target: return left return -1
-------------------------------------------------------------------------
38.Search a 2D Matrix II
Search for a value in an m x n matrix, return the occurrence of it.
This matrix has the following properties:
- Integers in each row are sorted from left to right.
- Integers in each column are sorted from up to bottom.
- No duplicate integers in each row or column.
class Solution: """ @param matrix: An list of lists of integers @param target: An integer you want to search in matrix @return: An integer indicates the total occurrence of target in the given matrix """ def searchMatrix(self, matrix, target): # write your code here result = 0 if not matrix or target is None: return result row = len(matrix) - 1 col = 0 while col <= len(matrix[0]) - 1 and row >= 0: if matrix[row][col] < target: col += 1 elif matrix[row][col] > target: row -= 1 else: result += 1 col += 1 row -= 1 return result
17.4.10二刷:
主對角線方向入手的,加入二分
class Solution: """ @param matrix: An list of lists of integers @param target: An integer you want to search in matrix @return: An integer indicates the total occurrence of target in the given matrix """ def searchMatrix(self, matrix, target): # write your code here if not matrix or not matrix[0]: return 0 m, n, result = len(matrix), len(matrix[0]), 0 row, col = 0, 0 while row < m and col < n and matrix[row][col] <= target: if matrix[row][col] == target: result += 1 else: if self.binSearch(matrix, row, col, 'row', target) != -1: result += 1 if self.binSearch(matrix, col, row, 'col', target) != -1: result += 1 row += 1 col += 1 return result def binSearch(self, matrix, index, start, type, target): left, right = start, len(matrix[0]) - 1 if type == 'row' else len(matrix) - 1 while left + 1 < right: mid = (right - left) / 2 + left if type == 'row' and matrix[index][mid] < target: left = mid elif type == 'col' and matrix[mid][index] < target: left = mid else: right = mid if type == 'row': if matrix[index][left] == target: return left elif matrix[index][right] == target: return right return -1 else: if matrix[left][index] == target: return left elif matrix[right][index] == target: return right return -1
-------------------------------------------------------------------------
457.Classical Binary Search
17.4.10二刷
class Solution: # @param {int[]} A an integer array sorted in ascending order # @param {int} target an integer # @return {int} an integer def findPosition(self, A, target): # Write your code here if not A or target is None: return -1 left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[mid] < target: left = mid elif A[mid] == target: return mid else: right = mid if A[left] == target: return left if A[right] == target: return right return -1
-------------------------------------------------------------------------
141.Sqrt(x)
Compute and return the square root of x. return int.
class Solution: """ @param x: An integer @return: The sqrt of x """ def sqrt(self, x): # write your code here if not x: return 0 left = 1 right = x while left + 1 < right: mid = (right - left) / 2 + left if mid ** 2 <= x: left = mid else: right = mid if right ** 2 <= x: return right if left ** 2 <= x: return left return 0
17.4.10二刷
class Solution: """ @param x: An integer @return: The sqrt of x """ def sqrt(self, x): # write your code here left, right = 0, x while left + 1 < right: mid = (right - left) / 2 + left if mid ** 2 >= x: right = mid else: left = mid if left ** 2 >= x: return left if left ** 2 == x else left - 1 return right if right ** 2 == x else right - 1
-------------------------------------------------------------------------
617.Maximum Average Subarray
尋找平均值最大的,長度大於等於k的子數組
首先利用二分思想找到潛在的最大值。
在計算前綴和的平均值時,有個巧妙的變化:每一項都減去mid,如果存在一個子數組(長度大於k)的和>0,就是說明存在一個子數組的和大於mid。這樣就變成了傳統的最大子數組問題。
class Solution: # @param {int[]} nums an array with positive and negative numbers # @param {int} k an integer # @return {double} the maximum average def maxAverage(self, nums, k): # Write your code here left, right = min(nums), max(nums) prefix = [0] * (len(nums) + 1) while right - left >= 1e-6: mid, check = (right + left) / 2.0, False min_pre = 0 for i in xrange(1, len(nums) + 1): prefix[i] = prefix[i - 1] + nums[i - 1] - mid if i >= k and prefix[i] >= min_pre: check = True break if i >= k: min_pre = min(min_pre, prefix[i - k + 1]) if check: left = mid else: right = mid return left
17.4.20二刷:
class Solution: # @param {int[]} nums an array with positive and negative numbers # @param {int} k an integer # @return {double} the maximum average def maxAverage(self, nums, k): # Write your code here left, right = min(nums), max(nums) prefix = [0] * (len(nums) + 1) while right - left > 1e-6: mid = (left + right) / 2.0 min_pre = 0 check = False for i in xrange(1, len(nums) + 1): prefix[i] = prefix[i - 1] + nums[i - 1] - mid if i >= k and prefix[i] > min_pre: check = True break if i >= k: min_pre = min(min_pre, prefix[i - k + 1]) if check: left = mid else: right = mid return right
-------------------------------------------------------------------------
586.Sqrt(x) II
注意小於1的時候,不需要double check
17.4.10
class Solution: # @param {double} x a double # @return {double} the square root of x def sqrt(self, x): # Write your code here if not x: return 0 # binary on result left = 0.0 right = x if x > 1 else 1 while left + 1e-12< right: mid = (right - left) / 2.0 + left midSquare = mid ** 2 if midSquare < x: left = mid else: right = mid # or u can return right return right
-------------------------------------------------------------------------
160.Find Minimum in Rotated Sorted Array II
Suppose a sorted array is rotated at some pivot unknown to you beforehand.
The array may contain duplicates.
class Solution: # @param num: a rotated sorted array # @return: the minimum number in the array def findMin(self, nums): # write your code here if not nums: return -1 left = 0 right = len(nums) - 1 while left + 1 < right: mid = (right - left) / 2 + left if nums[mid] < nums[right]: right = mid elif nums[mid] > nums[right]: left = mid else: if self.judge(nums, mid, right): right = mid else: left = mid return nums[left] if nums[left] < nums[right] else nums[right] def judge(self, A, mid, right): temp = None for i in A[mid:right + 1]: if temp is None or i == temp: temp = i else: return False return True
17.4.10二刷
class Solution: # @param num: a rotated sorted array # @return: the minimum number in the array def findMin(self, num): # write your code here left, right = 0, len(num) - 1 while left + 1 < right: if num[left] < num[right]: return num[left] mid = (right - left) / 2 + left if num[mid] > num[left]: left = mid elif num[mid] < num[right]: right = mid elif num[mid] == num[right] and num[mid] < num[left]: right = mid elif num[mid] == num[left] and num[mid] > num[right]: left = mid else: flag = False for i in xrange(left, mid + 1): if num[i] != num[left]: flag = True break if not flag: left = mid else: right = mid return num[left] if num[left] < num[right] else num[right]
-------------------------------------------------------------------------
63.Search in Rotated Sorted Array II
Follow up for Search in Rotated Sorted Array:What if duplicates are allowed?
class Solution: """ @param A : an integer ratated sorted array and duplicates are allowed @param target : an integer to be searched @return : a boolean """ def search(self, A, target): # write your code here if not A or target is None: return False left = 0 right = len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[right] < target: if A[mid] < A[right]: right = mid elif A[mid] == A[right]: if self.judge(A, left, mid, right): left = mid else: right = mid elif A[mid] > target: right = mid else: left = mid else: if A[mid] < target: left = mid elif A[mid] > A[right]: left = mid elif A[mid] == A[right]: if self.judge(A, left, mid, right): left = mid else: right = mid else: right = mid if A[left] == target: return True if A[right] == target: return True return False def judge(self, A, left, mid, right): temp = None for i in A[left:mid + 1]: if temp is None or i == temp: temp = i else: return False return True
17.4.10二刷
class Solution: """ @param A : an integer ratated sorted array and duplicates are allowed @param target : an integer to be searched @return : a boolean """ def search(self, A, target): # write your code here if not A or target is None: return False left, right = 0, len(A) - 1 while left + 1 < right: mid = (right - left) / 2 + left if A[left] < A[right]: if target > A[mid]: left = mid elif target < A[mid]: right = mid else: return True else: if target < A[right]: if A[mid] < target or A[mid] > A[left]: left = mid elif A[mid] > target: right = target else: return True elif target > A[left]: if A[mid] < A[right] or A[mid] > target: right = mid elif A[mid] < target: left = mid else: return True else: return True if A[left] == target or A[right] == target: return True return False
-------------------------------------------------------------------------
437.Copy Books
二分答案
class Solution: # @param pages: a list of integers # @param k: an integer # @return: an integer def copyBooks(self, pages, k): # write your code here if not pages or not k: return 0 left = max(pages) right = sum(pages) while left + 1 < right: mid = (right - left) / 2 + left staffCount = self.copyHelper(pages, mid) if staffCount <= k: right = mid else: left = mid if self.copyHelper(pages, left) <= k: return left else: return right def copyHelper(self, pages, maxWork): result = 0 temp = 0 for page in pages: if temp + page <= maxWork: temp += page else: temp = page result += 1 result += 1 return result
17.4.10二刷:
class Solution: # @param pages: a list of integers # @param k: an integer # @return: an integer def copyBooks(self, pages, k): # write your code here left, right = 0, sum(pages) while left + 1 < right: mid = (right - left) / 2 + left if self.check(pages, k, mid): right = mid else: left = mid if self.check(pages, k, left): return left return right def check(self, pages, k, cost): person = 1 work = 0 for p in pages: if p > cost: return False if work + p <= cost: work += p else: person += 1 work = p return person <= k
-------------------------------------------------------------------------
183.Wood Cut
把這些木頭切割成一些長度相同的小段木頭,小段的數目至少為 k,
小段越長越好。
class Solution: """ @param L: Given n pieces of wood with length L[i] @param k: An integer return: The maximum length of the small pieces. """ def woodCut(self, L, k): # write your code here if not L or not k: return 0 left = 1 right = max(L) while left + 1 < right: mid = (right - left) / 2 + left maxNum = self.checkWood(L, mid) if maxNum >= k: left = mid else: right = mid if self.checkWood(L, right) >= k: return right if self.checkWood(L, left) >= k: return left return 0 def checkWood(self, L, length): result = 0 for wood in L: result += wood / length return result
17.4.10二刷
class Solution: """ @param L: Given n pieces of wood with length L[i] @param k: An integer return: The maximum length of the small pieces. """ def woodCut(self, L, k): # write your code here if not L: return 0 left, right = 0, max(L) while left + 1 < right: mid = (right - left) / 2 + left if self.check(L, k, mid): left = mid else: right = mid if self.check(L, k, right): return right return left def check(self, L, k, length): result = 0 for l in L: result += l / length return result >= k
3 - 二叉樹與分治法
597.Subtree with Maximum Average
求最大的子樹平均值
""" Definition of TreeNode: class TreeNode: def __init__(self, val): this.val = val this.left, this.right = None, None """ class Solution: # @param {TreeNode} root the root of binary tree # @return {TreeNode} the root of the maximum average of subtree def findSubtree2(self, root): # Write your code here self.maxAvgNode = None self.maxAvg = None self.dcFind(root) return self.maxAvgNode def dcFind(self, root): if not root: return {'size': 0, 'sum': 0} leftSub = self.dcFind(root.left) rightSub = self.dcFind(root.right) result = { 'size': leftSub['size'] + rightSub['size'] + 1, 'sum': leftSub['sum'] + rightSub['sum'] + root.val } if not self.maxAvgNode or self.maxAvg['sum'] * result['size'] \ < result['sum'] * self.maxAvg['size']: self.maxAvgNode = root self.maxAvg = result return result
17.4.20二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): this.val = val this.left, this.right = None, None """ import sys class Solution: # @param {TreeNode} root the root of binary tree # @return {TreeNode} the root of the maximum average of subtree def findSubtree2(self, root): # Write your code here self.max_average = -sys.maxint self.result_node = None self.helper(root) return self.result_node def helper(self, root): if not root: return 0, 0 left_sum, left_count = self.helper(root.left) right_sum, right_count = self.helper(root.right) if (left_sum + right_sum + root.val) / float(left_count + right_count + 1) > self.max_average: self.max_average = (left_sum + right_sum + root.val) / float(left_count + right_count + 1) self.result_node = root return (left_sum + right_sum + root.val), (left_count + right_count + 1)
-------------------------------------------------------------------------
93.Balanced Binary Tree
檢查一棵樹是不是平衡的
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: True if this Binary tree is Balanced, or false. """ def isBalanced(self, root): # write your code here return self.traversalHelper(root)[1] def traversalHelper(self, root): if not root: return 0, True ldepth, lresult = self.traversalHelper(root.left) if lresult: rdepth, rresult = self.traversalHelper(root.right) if rresult: return max(ldepth, rdepth) + 1, abs(ldepth - rdepth) <= 1 else: return max(ldepth, rdepth) + 1, False else: return ldepth + 1, False
17.4.20二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: True if this Binary tree is Balanced, or false. """ def isBalanced(self, root): # write your code here return False if self.helper(root) == -1 else True def helper(self, root): if not root: return 0 left = self.helper(root.left) right = self.helper(root.right) if left == -1 or right == -1: return -1 if abs(left - right) > 1: return -1 return max(left, right) + 1
-------------------------------------------------------------------------
97.Maximum Depth of Binary Tree
返回一個二叉樹的最大深度
class Solution: """ @param root: The root of binary tree. @return: An integer """ def maxDepth(self, root): # write your code here return self.traversalHelper(root, 0) def traversalHelper(self, root, depth): if not root: return depth return max( self.traversalHelper(root.left, depth + 1), self.traversalHelper(root.right, depth + 1) )
17.4.20二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: An integer """ def maxDepth(self, root): # write your code here if not root: return 0 return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
-------------------------------------------------------------------------
480.Binary Tree Paths
找到二叉樹到葉子節點所有路徑
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: # @param {TreeNode} root the root of the binary tree # @return {List[str]} all root-to-leaf paths def binaryTreePaths(self, root): # Write your code here result = [] self.traversalHelper(root, result, []) return result def traversalHelper(self, root, result, path): if not root: return path.append(str(root.val)) if not root.left and not root.right: result.append('->'.join(path)) return self.traversalHelper(root.left, result, path[:]) self.traversalHelper(root.right, result, path[:])
17.4.20二刷
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: # @param {TreeNode} root the root of the binary tree # @return {List[str]} all root-to-leaf paths def binaryTreePaths(self, root): # Write your code here result = self.helper(root) for i in xrange(len(result)): result[i] = '->'.join(result[i][::-1]) return result def helper(self, root): if not root: return [] if (not root.left) and (not root.right): return [[str(root.val)]] child = self.helper(root.left) child.extend(self.helper(root.right)) for li in child: li.append(str(root.val)) return child
-------------------------------------------------------------------------
376.Binary Tree Path Sum
找到二叉樹到葉子節點所有路徑,和為target的
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: # @param {TreeNode} root the root of binary tree # @param {int} target an integer # @return {int[][]} all valid paths def binaryTreePathSum(self, root, target): # Write your code here result = [] self.traverseHelper(root, [], target, result) return result def traverseHelper(self, root, path, target, result): if not root: return path.append(root.val) if root.left is None and root.right is None: if sum(path) == target: result.append(path) else: self.traverseHelper(root.left, path[:], target, result) self.traverseHelper(root.right, path[:], target, result)
17.4.20二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: # @param {TreeNode} root the root of binary tree # @param {int} target an integer # @return {int[][]} all valid paths def binaryTreePathSum(self, root, target): # Write your code here temp = self.helper(root) result = [] for i in xrange(len(temp)): if sum(temp[i]) == target: result.append(temp[i]) return result def helper(self, root): if not root: return [] if (not root.left) and (not root.right): return [[root.val]] child = self.helper(root.left) child.extend(self.helper(root.right)) for li in child: li.insert(0, root.val) return child
-------------------------------------------------------------------------
596.Minimum Subtree
找到二叉樹中的最小子樹
""" Definition of TreeNode: class TreeNode: def __init__(self, val): this.val = val this.left, this.right = None, None """ class Solution: # @param {TreeNode} root the root of binary tree # @return {TreeNode} the root of the minimum subtree def findSubtree(self, root): # Write your code here self.minSum = None self.minSumNode = None self.dcFind(root) return self.minSumNode def dcFind(self, root): if not root: return 0 result = self.dcFind(root.left) + self.dcFind(root.right) + root.val if not self.minSumNode or self.minSum > result: self.minSum = result self.minSumNode = root return result
17.4.20二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): this.val = val this.left, this.right = None, None """ class Solution: # @param {TreeNode} root the root of binary tree # @return {TreeNode} the root of the minimum subtree def findSubtree(self, root): # Write your code here self.min_sum = sys.maxint self.result_node = None self.helper(root) return self.result_node def helper(self, root): if not root: return 0 left_sum = self.helper(root.left) right_sum = self.helper(root.right) if left_sum + right_sum + root.val < self.min_sum: self.min_sum = left_sum + right_sum + root.val self.result_node = root return left_sum + right_sum + root.val
-------------------------------------------------------------------------
595.Binary Tree Longest Consecutive Sequence
尋找二叉樹中從上至下方向中的最長的連續序列,返回長度
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: # @param {TreeNode} root the root of binary tree # @return {int} the length of the longest consecutive sequence path def longestConsecutive(self, root): # Write your code here self.maxLength = 0 self.dcFind(root) return self.maxLength def dcFind(self, root): if not root: return { 'len': 0, 'val': -1 } left = self.dcFind(root.left) right = self.dcFind(root.right) result = {'len': 1,'val':root.val} if left['val'] == root.val + 1: result['len'] = left['len'] + 1 if right['val'] == root.val + 1 and result['len'] < right['len'] + 1: result['len'] = right['len'] + 1 if result['len'] > self.maxLength: self.maxLength = result['len'] return result
17.4.20二刷
# Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution: # @param {TreeNode} root the root of binary tree # @return {int} the length of the longest consecutive sequence path def longestConsecutive(self, root): # Write your code here self.max_len = 0 self.helper(root) return self.max_len def helper(self, root): if not root: return 0 left, right, result = 0, 0, 1 if root.left: left = self.helper(root.left) if root.val + 1 == root.left.val: result += left if root.right: right = self.helper(root.right) if root.val + 1 == root.right.val: result = max(right + 1, result) self.max_len = max(self.max_len, left, right, result) return result
-------------------------------------------------------------------------
453.Flatten Binary Tree to Linked List
將一個二叉樹轉換為鏈表
""" Definition of TreeNode: class TreeNode: def __init__(self, val): this.val = val this.left, this.right = None, None """ class Solution: # @param root: a TreeNode, the root of the binary tree # @return: nothing def flatten(self, root): # write your code here if not root: return self.traversalHelper(root) def traversalHelper(self, root): if root.right: self.traversalHelper(root.right) if root.left: self.traversalHelper(root.left) leftStart = root.left leftEnd = root.left while leftEnd.right: leftEnd = leftEnd.right root.left = None rightStart = root.right root.right = leftStart leftEnd.right = rightStart
17.4.20二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): this.val = val this.left, this.right = None, None """ class Solution: # @param root: a TreeNode, the root of the binary tree # @return: nothing def flatten(self, root): # write your code here if not root: return self.flatten(root.left) self.flatten(root.right) temp = root.right root.right = root.left root.left = None cur = root while cur.right: cur = cur.right cur.right = temp
-------------------------------------------------------------------------
578.Lowest Common Ancestor III
找兩個節點的最低公共祖先
""" Definition of TreeNode: class TreeNode: def __init__(self, val): this.val = val this.left, this.right = None, None """ class Solution: """ @param {TreeNode} root The root of the binary tree. @param {TreeNode} A and {TreeNode} B two nodes @return Return the LCA of the two nodes. """ def lowestCommonAncestor3(self, root, A, B): # write your code here result = self.dcHelper(root, A, B) return result['result'] def dcHelper(self, root, A, B): if not root: return { 'foundA': False, 'foundB': False, 'result': None } else: left = self.dcHelper(root.left, A, B) right = self.dcHelper(root.right, A, B) result = { 'foundA': left['foundA'] or right['foundA'], 'foundB': left['foundB'] or right['foundB'], 'result': left['result'] if left['result'] else right['result'] } if root == A: result['foundA'] = True if root == B: result['foundB'] = True if result['result'] is None and result['foundA'] and result['foundB']: result['result'] = root return result
17.4.21二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): this.val = val this.left, this.right = None, None """ class Solution: """ @param {TreeNode} root The root of the binary tree. @param {TreeNode} A and {TreeNode} B two nodes @return Return the LCA of the two nodes. """ def lowestCommonAncestor3(self, root, A, B): # write your code here pathA = self.get_path(root, A, [root]) pathB = self.get_path(root, B, [root]) if not pathA or not pathB: return for i in range(min(len(pathA), len(pathB))): if pathA[i] != pathB[i]: return pathA[i - 1] return pathA[-1] if len(pathA) < len(pathB) else pathB[-1] def get_path(self, root, target, path): if not root: return [] if root == target: return path for node in (root.left, root.right): path.append(node) result = self.get_path(node, target, path) if result: return result path.pop()
-------------------------------------------------------------------------
95.Validate Binary Search Tree
驗證是不是二叉查找樹,左子樹嚴格小於根,右子樹嚴格大於根
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: True if the binary tree is BST, or false """ def isValidBST(self, root): result = self.dcHelper(root) return result['result'] def dcHelper(self, root): if not root: return {'result': True, 'min': None, 'max': None} else: left = self.dcHelper(root.left) right = self.dcHelper(root.right) if not left['result'] or not right['result']: return {'result': False, 'min': None, 'max': None} elif (left['max'] and left['max'] >= root.val) \ or (right['min'] and right['min'] <= root.val): return {'result': False, 'min': None, 'max': None} else: return { 'result': True, 'min': left['min'] if left['min'] else root.val, 'max': right['max'] if right['max'] else root.val }
17.4.21二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ import sys class Solution: """ @param root: The root of binary tree. @return: True if the binary tree is BST, or false """ def isValidBST(self, root): # write your code here self.result = True self.testBST(root) return self.result def testBST(self, root): if not root: return sys.maxint, -sys.maxint lsmall, lbig = self.testBST(root.left) rsmall, rbig = self.testBST(root.right) if lbig >= root.val or rsmall <= root.val: self.result = False return min(lsmall, root.val), max(rbig, root.val)
-------------------------------------------------------------------------
474.Lowest Common Ancestor II
最小公共祖先,有指向父節點的指針
""" Definition of ParentTreeNode: class ParentTreeNode: def __init__(self, val): self.val = val self.parent, self.left, self.right = None, None, None """ class Solution: """ @param root: The root of the tree @param A and B: Two node in the tree @return: The lowest common ancestor of A and B """ def lowestCommonAncestorII(self, root, A, B): # Write your code here parentA = [] while A: parentA.append(A) A = A.parent while B: if B in parentA: return B B = B.parent
17.4.21二刷:
""" Definition of ParentTreeNode: class ParentTreeNode: def __init__(self, val): self.val = val self.parent, self.left, self.right = None, None, None """ class Solution: """ @param root: The root of the tree @param A and B: Two node in the tree @return: The lowest common ancestor of A and B """ def lowestCommonAncestorII(self, root, A, B): # Write your code here pA = self.get_parent_list(A) pB = self.get_parent_list(B) if not pA or not pB: return for i in range(min(len(pA), len(pB))): if pA[i] != pB[i]: return pA[i - 1] return pA[-1] if len(pA) < len(pB) else pB[-1] def get_parent_list(self, node): result = [] cur = node while cur: result.append(cur) cur = cur.parent return result[::-1]
-------------------------------------------------------------------------
246.Binary Tree Path Sum II
任意位置開始和結束,只能從上往下
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: # @param {TreeNode} root the root of binary tree # @param {int} target an integer # @return {int[][]} all valid paths def binaryTreePathSum2(self, root, target): # Write your code here self.result = [] if target is None: return self.result self.dcHelper(root, target) return self.result def dcHelper(self, root, target): dcResult = [] if not root: return dcResult temp = self.dcHelper(root.left, target) temp.extend(self.dcHelper(root.right, target)) #dcResult.extend(temp) temp.append([]) for path in temp: path.insert(0, root.val) if sum(path) == target: self.result.append(path[:]) dcResult.append(path[:]) return dcResult
17.4.21二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: # @param {TreeNode} root the root of binary tree # @param {int} target an integer # @return {int[][]} all valid paths def binaryTreePathSum2(self, root, target): # Write your code here self.result = [] paths = self.helper(root, target) return self.result def helper(self, root, target): if not root: return [] result = self.helper(root.left, target) result.extend(self.helper(root.right, target)) for i in xrange(len(result)): result[i].append(root.val) result.append([root.val]) for i in xrange(len(result)): if result[i] and sum(result[i]) == target: self.result.append(result[i][::-1]) return result
-------------------------------------------------------------------------
68.Binary Tree Postorder Traversal
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: Postorder in ArrayList which contains node values. """ def postorderTraversal(self, root): # write your code here result = [] if not root: return result now = root markNode = None stack = [] while stack or now: while now: stack.append(now) now = now.left now = stack.pop() if not now.right or now.right is markNode: result.append(now.val) markNode = now now = None else: stack.append(now) now = now.right return result
17.4.21二刷,遞歸版本,要背過非遞歸的
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: Postorder in ArrayList which contains node values. """ def postorderTraversal(self, root): # write your code here self.result = [] self.helper(root) return self.result def helper(self, root): if not root: return self.helper(root.left) self.helper(root.right) self.result.append(root.val)
-------------------------------------------------------------------------
67.Binary Tree Inorder Traversal
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: Inorder in ArrayList which contains node values. """ def inorderTraversal(self, root): # write your code here result = [] if root is None: return result stack = [] now = root while now or stack: while now: stack.append(now) now = now.left now = stack.pop() result.append(now.val) now = now.right return result
17.4.21二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: Inorder in ArrayList which contains node values. """ def inorderTraversal(self, root): # write your code here self.result = [] self.helper(root) return self.result def helper(self, root): if not root: return self.helper(root.left) self.result.append(root.val) self.helper(root.right)
-------------------------------------------------------------------------
66.Binary Tree Preorder Traversal
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: Preorder in ArrayList which contains node values. """ def preorderTraversal(self, root): # write your code here result = [] self.traversalHelper(root, result) return result def traversalHelper(self, root, result): if not root: return result.append(root.val) self.traversalHelper(root.left, result) self.traversalHelper(root.right, result)
17.4.21二刷:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: The root of binary tree. @return: Preorder in ArrayList which contains node values. """ def preorderTraversal(self, root): # write your code here self.result = [] self.helper(root) return self.result def helper(self, root): if not root: return self.result.append(root.val) self.helper(root.left) self.helper(root.right)
-------------------------------------------------------------------------
4 - 寬度優先搜索
7.binary-tree-serialization
設計一個算法,並編寫代碼來序列化和反序列化二叉樹。

1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 self.val = val 6 self.left, self.right = None, None 7 """ 8 class Solution: 9 10 ''' 11 @param root: An object of TreeNode, denote the root of the binary tree. 12 This method will be invoked first, you should design your own algorithm 13 to serialize a binary tree which denote by a root node to a string which 14 can be easily deserialized by your own "deserialize" method later. 15 ''' 16 def serialize(self, root): 17 # write your code here 18 result = [] 19 if not root: 20 return ','.join(result) 21 22 queue = [root] 23 while queue: 24 node = queue.pop(0) 25 result.append(str(node.val) if node else '#') 26 if node: 27 queue.append(node.left) 28 queue.append(node.right) 29 return ','.join(result) 30 31 ''' 32 @param data: A string serialized by your serialize method. 33 This method will be invoked second, the argument data is what exactly 34 you serialized at method "serialize", that means the data is not given by 35 system, it's given by your own serialize method. So the format of data is 36 designed by yourself, and deserialize it here as you serialize it in 37 "serialize" method. 38 ''' 39 def deserialize(self, data): 40 # write your code here 41 root = None 42 if not data: 43 return root 44 data = data.split(',') 45 46 root = TreeNode(int(data[0])) 47 queue = [root] 48 isLeftChild = True 49 index = 0 50 51 for val in data[1:]: 52 if val is not '#': 53 node = TreeNode(int(val)) 54 if isLeftChild: 55 queue[index].left = node 56 else: 57 queue[index].right = node 58 queue.append(node) 59 60 if not isLeftChild: 61 index += 1 62 isLeftChild = not isLeftChild 63 64 return root 65
17.5.29二刷
序列化時加入父節點信息和左右信息

1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 self.val = val 6 self.left, self.right = None, None 7 """ 8 import json 9 class Solution: 10 11 ''' 12 @param root: An object of TreeNode, denote the root of the binary tree. 13 This method will be invoked first, you should design your own algorithm 14 to serialize a binary tree which denote by a root node to a string which 15 can be easily deserialized by your own "deserialize" method later. 16 ''' 17 def serialize(self, root): 18 # write your code here 19 result = [] 20 queue = [[None, None, root]] if root else [] 21 i = -1 22 while queue: 23 node = queue.pop(0) 24 result.append([node[0], node[1], node[2].val]) 25 i += 1 26 if node[2].left: 27 queue.append([i, 0, node[2].left]) 28 if node[2].right: 29 queue.append([i, 1, node[2].right]) 30 return json.dumps(result) 31 32 ''' 33 @param data: A string serialized by your serialize method. 34 This method will be invoked second, the argument data is what exactly 35 you serialized at method "serialize", that means the data is not given by 36 system, it's given by your own serialize method. So the format of data is 37 designed by yourself, and deserialize it here as you serialize it in 38 "serialize" method. 39 ''' 40 def deserialize(self, data): 41 # write your code here 42 result = json.loads(data) 43 for i in range(len(result)): 44 temp = result[i] 45 result[i] = TreeNode(result[i][2]) 46 if not temp[0] is None: 47 if temp[1] == 0: 48 result[temp[0]].left = result[i] 49 if temp[1] == 1: 50 result[temp[0]].right = result[i] 51 return result[0] if result else None
-------------------------------------------------------------------------
70.binary-tree-level-order-traversal-ii
給出一棵二叉樹,返回其節點值從底向上的層次序遍歷(按從葉節點所在層到根節點所在的層遍歷,然后逐層從左往右遍歷)

1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 self.val = val 6 self.left, self.right = None, None 7 """ 8 9 10 class Solution: 11 """ 12 @param root: The root of binary tree. 13 @return: buttom-up level order in a list of lists of integers 14 """ 15 def levelOrderBottom(self, root): 16 # write your code here 17 result = [] 18 if not root: 19 return result 20 queue = [root] 21 while queue: 22 size = len(queue) 23 level = [] 24 for i in range(size): 25 node = queue.pop(0) 26 level.append(node.val) 27 if node.left: 28 queue.append(node.left) 29 if node.right: 30 queue.append(node.right) 31 result.append(level) 32 return result[::-1]
17.5.29二刷

1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 self.val = val 6 self.left, self.right = None, None 7 """ 8 9 10 class Solution: 11 """ 12 @param root: The root of binary tree. 13 @return: buttom-up level order in a list of lists of integers 14 """ 15 def levelOrderBottom(self, root): 16 # write your code here 17 if not root: 18 return [] 19 result = [] 20 queue = [root] 21 while queue: 22 size = len(queue) 23 tmp = [] 24 for i in range(size): 25 node = queue.pop(0) 26 tmp.append(node.val) 27 if node.left: 28 queue.append(node.left) 29 if node.right: 30 queue.append(node.right) 31 result.append(tmp) 32 return result[::-1]
-------------------------------------------------------------------------
71.binary-tree-zigzag-level-order-traversal
給出一棵二叉樹,返回其節點值的鋸齒形層次遍歷(先從左往右,下一層再從右往左,層與層之間交替進行)

1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 self.val = val 6 self.left, self.right = None, None 7 """ 8 9 10 class Solution: 11 """ 12 @param root: The root of binary tree. 13 @return: A list of list of integer include 14 the zig zag level order traversal of its nodes' values 15 """ 16 def zigzagLevelOrder(self, root): 17 # write your code here 18 result = [] 19 if not root: 20 return result 21 queue = [root] 22 flag = True 23 while queue: 24 size = len(queue) 25 level = [] 26 for i in range(size): 27 node = queue.pop(0) 28 level.append(node.val) 29 if node.left: 30 queue.append(node.left) 31 if node.right: 32 queue.append(node.right) 33 result.append(level if flag else level[::-1]) 34 flag = not flag 35 return result
17.5.29二刷

1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 self.val = val 6 self.left, self.right = None, None 7 """ 8 9 10 class Solution: 11 """ 12 @param root: The root of binary tree. 13 @return: A list of list of integer include 14 the zig zag level order traversal of its nodes' values 15 """ 16 def zigzagLevelOrder(self, root): 17 # write your code here 18 result = [] 19 if not root: 20 return result 21 queue = [root] 22 reverse = False 23 while queue: 24 size = len(queue) 25 tmp = [] 26 for i in range(size): 27 node = queue.pop(0) 28 tmp.append(node.val) 29 if node.left: 30 queue.append(node.left) 31 if node.right: 32 queue.append(node.right) 33 result.append(tmp if not reverse else tmp[::-1]) 34 reverse = not reverse 35 return result
-------------------------------------------------------------------------
120.word-ladder
給出兩個單詞(start和end)和一個字典,找到從start到end的最短轉換序列
比如:
- 每次只能改變一個字母。
- 變換過程中的中間單詞必須在字典中出現。

1 class Solution: 2 # @param start, a string 3 # @param end, a string 4 # @param dict, a set of string 5 # @return an integer 6 def ladderLength(self, start, end, dict): 7 # write your code here 8 queue = [start] 9 visited = set([start]) 10 level = 0 11 dict.add(start) 12 dict.add(end) 13 14 while queue: 15 level += 1 16 size = len(queue) 17 for i in range(size): 18 word = queue.pop(0) 19 if word == end: 20 return level 21 for item in self.find_neighbors(word, dict): 22 if item in visited: 23 continue 24 visited.add(item) 25 queue.append(item) 26 27 def find_neighbors(self, word, dict): 28 result = [] 29 for i in range(len(word)): 30 code = ord(word[i]) 31 for j in range(97, 123): 32 if j == code: 33 continue 34 string = word[:i] + chr(j) + word[i + 1:] 35 if string in dict: 36 result.append(string) 37 return result
17.5.29二刷

1 class Solution: 2 # @param start, a string 3 # @param end, a string 4 # @param dict, a set of string 5 # @return an integer 6 def ladderLength(self, start, end, dict): 7 # write your code here 8 if start == end: 9 return 1 10 dict = set(dict) 11 visited = set([start]) 12 queue = [start] 13 step = 0 14 while queue: 15 step += 1 16 size = len(queue) 17 for i in range(size): 18 word = queue.pop(0) 19 for w in self.findNeighbors(word): 20 if w == end: 21 return step + 1 22 if w in dict and w not in visited: 23 visited.add(w) 24 queue.append(w) 25 return 0 26 27 28 def findNeighbors(self, word): 29 result = [] 30 for i in range(len(word)): 31 for j in range(97, 123): 32 result.append(word[:i] + chr(j) + word[i + 1:]) 33 return result
-------------------------------------------------------------------------
127.topological-sorting
給定一個有向圖,圖節點的拓撲排序被定義為:
- 對於每條有向邊A--> B,則A必須排在B之前
- 拓撲排序的第一個節點可以是任何在圖中沒有其他節點指向它的節點
找到給定圖的任一拓撲排序

1 # Definition for a Directed graph node 2 # class DirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 7 class Solution: 8 """ 9 @param graph: A list of Directed graph node 10 @return: A list of graph nodes in topological order. 11 """ 12 def topSort(self, graph): 13 # write your code here 14 result = [] 15 if not graph: 16 return result 17 18 for node in graph: 19 for n in node.neighbors: 20 if hasattr(n, 'in_degree'): 21 n.in_degree += 1 22 else: 23 n.in_degree = 1 24 25 queue = [] 26 for node in graph: 27 if not hasattr(node, 'in_degree') or node.in_degree == 0: 28 queue.append(node) 29 while queue: 30 node = queue.pop(0) 31 result.append(node) 32 for n in node.neighbors: 33 n.in_degree -= 1 34 if n.in_degree == 0: 35 queue.append(n) 36 return result
17.5.29二刷

1 # Definition for a Directed graph node 2 # class DirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 7 class Solution: 8 """ 9 @param graph: A list of Directed graph node 10 @return: A list of graph nodes in topological order. 11 """ 12 def topSort(self, graph): 13 # write your code here 14 map = {} 15 for node in graph: 16 map[node.label] = {'parents':0, \ 17 'children':[n.label for n in node.neighbors], 18 'node':node} 19 for node in graph: 20 for c in map[node.label]['children']: 21 map[c]['parents'] += 1 22 23 queue = [key for key in map if map[key]['parents'] == 0] 24 result = [] 25 while queue: 26 node = queue.pop(0) 27 result.append(map[node]['node']) 28 for c in map[node]['children']: 29 map[c]['parents'] -= 1 30 if map[c]['parents'] == 0: 31 queue.append(c) 32 33 return result
-------------------------------------------------------------------------
618.search-graph-nodes
Given a undirected graph
, a node
and a target
, return the nearest node to given node which value of it is target, return NULL
if you can't find.

1 # Definition for a undirected graph node 2 # class UndirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 7 class Solution: 8 # @param {UndirectedGraphNode[]} graph a list of undirected graph node 9 # @param {dict} values a dict, <UndirectedGraphNode, (int)value> 10 # @param {UndirectedGraphNode} node an Undirected graph node 11 # @param {int} target an integer 12 # @return {UndirectedGraphNode} a node 13 def searchNode(self, graph, values, node, target): 14 # Write your code here 15 if not graph or not node or not values or target is None: 16 return None 17 queue = [node] 18 while queue: 19 nd = queue.pop(0) 20 if values[nd] == target: 21 return nd 22 for neighbor in nd.neighbors: 23 queue.append(neighbor) 24 return None
17.5.30二刷

1 # Definition for a undirected graph node 2 # class UndirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 7 class Solution: 8 # @param {UndirectedGraphNode[]} graph a list of undirected graph node 9 # @param {dict} values a dict, <UndirectedGraphNode, (int)value> 10 # @param {UndirectedGraphNode} node an Undirected graph node 11 # @param {int} target an integer 12 # @return {UndirectedGraphNode} a node 13 def searchNode(self, graph, values, node, target): 14 # Write your code here 15 queue = [node] 16 visited = set([node]) 17 while queue: 18 node = queue.pop(0) 19 if values[node] == target: 20 return node 21 for child in node.neighbors: 22 if child not in visited: 23 visited.add(child) 24 queue.append(child)
-------------------------------------------------------------------------
616.course-schedule-ii
拓撲排序

1 class Solution: 2 # @param {int} numCourses a total of n courses 3 # @param {int[][]} prerequisites a list of prerequisite pairs 4 # @return {int[]} the course order 5 def findOrder(self, numCourses, prerequisites): 6 # Write your code here 7 nodes = {} 8 queue = [] 9 result = [] 10 for i in range(numCourses): 11 nodes[i] = { 12 'pre' : 0, 13 'next' : [] 14 } 15 for p in prerequisites: 16 nodes[p[0]]['pre'] += 1 17 nodes[p[1]]['next'].append(p[0]) 18 19 for key in nodes: 20 if nodes[key]['pre'] == 0: 21 queue.append(key) 22 23 while queue: 24 node = queue.pop(0) 25 result.append(node) 26 for next in nodes[node]['next']: 27 nodes[next]['pre'] -= 1 28 if nodes[next]['pre'] == 0: 29 queue.append(next) 30 31 return result if len(result) == numCourses else [] 32 33
17.5.30二刷

1 class Solution: 2 # @param {int} numCourses a total of n courses 3 # @param {int[][]} prerequisites a list of prerequisite pairs 4 # @return {int[]} the course order 5 def findOrder(self, numCourses, prerequisites): 6 # Write your code here 7 graph = {} 8 queue = [] 9 result = [] 10 for i in range(numCourses): 11 graph[i] = { 12 'pre' : 0, 13 'next' : [] 14 } 15 for p in prerequisites: 16 graph[p[0]]['pre'] += 1 17 graph[p[1]]['next'].append(p[0]) 18 for i in graph: 19 if graph[i]['pre'] == 0: 20 queue.append(i) 21 22 # bfs 23 while queue: 24 node = queue.pop(0) 25 result.append(node) 26 for child in graph[node]['next']: 27 graph[child]['pre'] -= 1 28 if graph[child]['pre'] == 0: 29 queue.append(child) 30 return result if len(result) == numCourses else [] 31
-------------------------------------------------------------------------
611.knight-shortest-path
Given a knight in a chessboard (a binary matrix with 0
as empty and 1
as barrier) with a source
position, find the shortest path to a destination
position, return the length of the route.
Return -1
if knight can not reached.

1 # Definition for a point. 2 # class Point: 3 # def __init__(self, a=0, b=0): 4 # self.x = a 5 # self.y = b 6 7 class Solution: 8 # @param {boolean[][]} grid a chessboard included 0 (False) and 1 (True) 9 # @param {Point} source a point 10 # @param {Point} destination a point 11 # @return {int} the shortest path 12 def shortestPath(self, grid, source, destination): 13 # Write your code here 14 row = len(grid) 15 if row == 0: 16 return 0 17 col = len(grid[0]) 18 19 jump = -1 20 visited = [[False for i in range(col)] for j in range(row)] 21 nbrow = [1, -1, 2, 2, 1, -1, -2, -2] 22 nbcol = [2, 2, 1, -1, -2, -2, 1, -1] 23 queue = [(source.x, source.y)] 24 while queue: 25 size = len(queue) 26 jump += 1 27 for s in range(size): 28 (x, y) = queue.pop(0) 29 if (x, y) == (destination.x, destination.y): 30 return jump 31 visited[x][y] = True 32 for i in range(8): 33 nx = x + nbrow[i] 34 ny = y + nbcol[i] 35 if nx >= 0 and nx < row and ny >= 0 and ny < col \ 36 and (not grid[nx][ny]) and (not visited[nx][ny]) \ 37 and ((nx, ny) not in queue): #最后一個條件非常重要,重復元素不入隊 38 queue.append((nx, ny)) 39 return -1 40 41 42
17.5.30二刷

1 # Definition for a point. 2 # class Point: 3 # def __init__(self, a=0, b=0): 4 # self.x = a 5 # self.y = b 6 7 class Solution: 8 # @param {boolean[][]} grid a chessboard included 0 (False) and 1 (True) 9 # @param {Point} source a point 10 # @param {Point} destination a point 11 # @return {int} the shortest path 12 def shortestPath(self, grid, source, destination): 13 # Write your code here 14 m, n = len(grid), len(grid[0]) 15 visited = [[0] * n for i in range(m)] 16 visited[source.x][source.y] = 1 17 queue = [source] 18 step = -1 19 axis_x = [1, 1, -1, -1, 2, 2, -2, -2] 20 axis_y = [2, -2, 2, -2, 1, -1, 1, -1] 21 while queue: 22 size = len(queue) 23 step += 1 24 for i in range(size): 25 pos = queue.pop(0) 26 if pos.x == destination.x and pos.y == destination.y: 27 return step 28 for j in range(len(axis_x)): 29 n_x, n_y = pos.x + axis_x[j], pos.y + axis_y[j] 30 if self.checkPos(grid, visited, n_x, n_y): 31 visited[n_x][n_y] = 1 32 queue.append(Point(n_x, n_y)) 33 return -1 34 35 def checkPos(self, grid, visited, x, y): 36 m, n = len(grid), len(grid[0]) 37 if not (0 <= x < m and 0 <= y < n): 38 return False 39 if visited[x][y] == 1: 40 return False 41 if grid[x][y] == 1: 42 return False 43 return True 44 45
-------------------------------------------------------------------------
598.zombie-in-matrix
Given a 2D grid, each cell is either a wall 2
, a zombie 1
or people 0
(the number zero, one, two).Zombies can turn the nearest people(up/down/left/right) into zombies every day, but can not through wall. How long will it take to turn all people into zombies? Return -1
if can not turn all people into zombies.

1 class Solution: 2 # @param {int[][]} grid a 2D integer grid 3 # @return {int} an integer 4 def zombie(self, grid): 5 # Write your code here 6 row = len(grid) 7 if row == 0: 8 return 0 9 col = len(grid[0]) 10 11 jump = -1 12 nbrow = [1, -1, 0, 0] 13 nbcol = [0, 0, 1, -1] 14 queue = [] 15 for r in range(row): 16 for c in range(col): 17 if grid[r][c] == 1: 18 queue.append((r,c)) 19 while queue: 20 size = len(queue) 21 jump += 1 22 for s in range(size): 23 (x, y) = queue.pop(0) 24 for i in range(4): 25 nx = x + nbrow[i] 26 ny = y + nbcol[i] 27 if nx >= 0 and nx < row and ny >= 0 and ny < col \ 28 and grid[nx][ny] == 0 and ((nx, ny) not in queue): 29 #æåä¸ä¸ªæ¡ä»¶é常éè¦ï¼éå¤å ç´ ä¸å ¥é 30 grid[nx][ny] = 1 31 queue.append((nx, ny)) 32 for r in range(row): 33 for c in range(col): 34 if grid[r][c] == 0: 35 return -1 36 return jump
17.5.30二刷

1 class Solution: 2 # @param {int[][]} grid a 2D integer grid 3 # @return {int} an integer 4 def zombie(self, grid): 5 # Write your code here 6 queue = [] 7 day = 0 8 cnt = 0 9 axis_x = [1, -1, 0, 0] 10 axis_y = [0, 0, 1, -1] 11 for i in range(len(grid)): 12 for j in range(len(grid[0])): 13 if grid[i][j] == 0: 14 cnt += 1 15 if grid[i][j] == 1: 16 queue.append([i, j]) 17 if cnt == 0: 18 return day 19 while queue: 20 size = len(queue) 21 day += 1 22 for i in range(size): 23 z = queue.pop(0) 24 for i in range(len(axis_x)): 25 x, y = z[0] + axis_x[i], z[1] + axis_y[i] 26 if self.check(grid, x, y): 27 grid[x][y] = 1 28 queue.append([x, y]) 29 cnt -= 1 30 if cnt == 0: 31 return day 32 return -1 33 34 def check(self, grid, x, y): 35 if not (0 <= x < len(grid) and 0 <= y < len(grid[0])): 36 return False 37 if grid[x][y] != 0: 38 return False 39 return True 40
-------------------------------------------------------------------------
573.build-post-office-ii
Given a 2D grid, each cell is either a wall 2
, an house 1
or empty 0
(the number zero, one, two), find a place to build a post office so that the sum of the distance from the post office to all the houses is smallest.
Return the smallest sum of distance. Return -1
if it is not possible.

1 class Solution: 2 # @param {int[][]} grid a 2D grid 3 # @return {int} an integer 4 def shortestDistance(self, grid): 5 # Write your code here 6 # 判斷當前節點是不是沒走過的empty節點 7 def isVaild(grid, r, c, row, col, visited): 8 if r >= 0 and r < row and c >= 0 and c < col \ 9 and grid[r][c] == 0 and (not visited[r][c]): 10 return True 11 return False 12 13 row = len(grid) 14 if row == 0: 15 return 0 16 col = len(grid[0]) 17 nbrow = [1, -1, 0, 0] 18 nbcol = [0, 0, 1, -1] 19 empty, wall, house, distance = self.initialize(grid, row, col) 20 for h in house: #對於每個房子BFS 21 jump = -1 22 queue = [h] 23 # visited distance等輔助數組,要使用最原始的數組 24 # (每個元素對應一個格子,存各種數據,而不是存格子下標) 25 # (不要用in查詢,增加復雜度) 26 visited = [[False for c in range(col)] for r in range(row)] 27 while queue: 28 jump += 1 29 size = len(queue) 30 for s in range(size): 31 node = queue.pop(0) 32 if grid[node[0]][node[1]] == 0: 33 distance[node[0]][node[1]] += jump 34 for i in range(4): 35 nx = node[0] + nbrow[i] 36 ny = node[1] + nbcol[i] 37 if isVaild(grid, nx, ny, row, col, visited): 38 visited[nx][ny] = True 39 queue.append((nx, ny)) 40 for i in range(row): 41 for j in range(col): 42 if not visited[i][j]: 43 # 假如當前empty,存在一個房子無法到達 44 # 那么以后郵局不可能選在它上面,路徑也不能通過它 45 # 標記為牆,以后不需要探測 46 grid[i][j] = 2 47 distance[i][j] = 99999 48 result = min([min(l) for l in distance]) 49 return result if result != 99999 else -1 50 51 def initialize(self, grid, row, col): 52 empty = [] 53 wall = [] 54 house = [] 55 distance = [[0 for c in range(col)] for r in range(row)] 56 for r in range(row): 57 for c in range(col): 58 if grid[r][c] == 1: 59 house.append((r, c)) 60 elif grid[r][c] == 2: 61 wall.append((r, c)) 62 else: 63 empty.append((r, c)) 64 for r, c in wall: 65 distance[r][c] = 99999 66 for r, c in house: 67 distance[r][c] = 99999 68 return empty, wall, house, distance
17.5.30二刷

1 class Solution: 2 # @param {int[][]} grid a 2D grid 3 # @return {int} an integer 4 def shortestDistance(self, grid): 5 # Write your code here 6 distance = [[0] * len(grid[0]) for i in range(len(grid))] 7 houses = [] 8 empties = set([]) 9 axis_x = [1, -1, 0, 0] 10 axis_y = [0, 0, 1, -1] 11 for i in range(len(grid)): 12 for j in range(len(grid[0])): 13 if grid[i][j] != 0: 14 distance[i][j] = 99999 15 if grid[i][j] == 1: 16 houses.append((i, j)) 17 else: 18 empties.add((i, j)) 19 20 for h in houses: 21 queue = [h] 22 visited = set(queue) 23 step = -1 24 while queue: 25 step += 1 26 size = len(queue) 27 for i in range(size): 28 pos = queue.pop(0) 29 distance[pos[0]][pos[1]] += step 30 for j in range(len(axis_x)): 31 x, y = pos[0] + axis_x[j], pos[1] + axis_y[j] 32 if self.check(grid, distance, visited, x, y): 33 visited.add((x, y)) 34 queue.append((x, y)) 35 diff = empties - visited 36 for d in diff: 37 distance[d[0]][d[1]] = 99999 38 m = min([min(line) for line in distance]) 39 return m if m < 99999 else -1 40 41 def check(self, grid, distance, visited, x, y): 42 if not (0 <= x < len(grid) and 0 <= y < len(grid[0])): 43 return False 44 return grid[x][y] == 0 and distance[x][y] < 99999 and (x, y) not in visited 45
-------------------------------------------------------------------------
433.number-of-islands
給一個01矩陣,求不同的島嶼的個數。
0代表海,1代表島,如果兩個1相鄰,那么這兩個1屬於同一個島。我們只考慮上下左右為相鄰。

1 class Solution: 2 # @param {boolean[][]} grid a boolean 2D matrix 3 # @return {int} an integer 4 def numIslands(self, grid): 5 # Write your code here 6 self.row = len(grid) 7 if self.row == 0: 8 return 0 9 self.col = len(grid[0]) 10 11 self.visited = [[False for i in range(self.col)] for j in range(self.row)] 12 count = 0 13 for r in range(self.row): 14 for c in range(self.col): 15 if self.check(grid, r, c): 16 self.bfs(grid, r, c) 17 count += 1 18 return count 19 20 def check(self, grid, r, c): 21 if r >= 0 and r < self.row and c >= 0 and c < self.col \ 22 and grid[r][c] and (not self.visited[r][c]): 23 return True 24 return False 25 26 def bfs(self, grid, r, c): 27 nbrow = [1, -1, 0, 0] 28 nbcol = [0, 0, 1, -1] 29 queue = [(r, c)] 30 while queue: 31 (x, y) = queue.pop(0) 32 self.visited[x][y] = True 33 for i in range(4): 34 nx = x + nbrow[i] 35 ny = y + nbcol[i] 36 if self.check(grid, nx, ny): 37 queue.append((nx, ny))
17.5.31二刷

1 class Solution: 2 # @param {boolean[][]} grid a boolean 2D matrix 3 # @return {int} an integer 4 def numIslands(self, grid): 5 # Write your code here 6 if not grid or not grid[0]: 7 return 0 8 m, n = len(grid), len(grid[0]) 9 visited = [[0] * n for i in range(m)] 10 result = 0 11 queue = [] 12 for i in range(m): 13 for j in range(n): 14 if grid[i][j] == 1 and visited[i][j] == 0: 15 visited[i][j] = 1 16 result += 1 17 queue.append((i, j)) 18 self.bfs(queue, grid, visited) 19 return result 20 21 def bfs(self, queue, grid, visited): 22 axis_x = [1, -1, 0, 0] 23 axis_y = [0, 0, 1, -1] 24 25 while queue: 26 node = queue.pop(0) 27 for i in range(4): 28 x = node[0] + axis_x[i] 29 y = node[1] + axis_y[i] 30 if self.check(grid, visited, x, y): 31 visited[x][y] = 1 32 queue.append((x, y)) 33 34 def check(self, grid, visited, x, y): 35 if not (0 <= x < len(grid) and 0 <= y < len(grid[0])): 36 return False 37 return grid[x][y] == 1 and visited[x][y] == 0 38 39
-------------------------------------------------------------------------
178.graph-valid-tree
給出 n
個節點,標號分別從 0
到 n - 1
並且給出一個 無向
邊的列表 (給出每條邊的兩個頂點), 寫一個函數去判斷這張`無向`圖是否是一棵樹

1 class Solution: 2 # @param {int} n an integer 3 # @param {int[][]} edges a list of undirected edges 4 # @return {boolean} true if it's a valid tree, or false 5 def validTree(self, n, edges): 6 # Write your code here 7 if not n or edges is None: 8 return False 9 if len(edges) != n - 1: 10 return False 11 12 graph = [] 13 for i in range(n): 14 graph.append(set([])) 15 for edge in edges: 16 graph[edge[0]].add(edge[1]) 17 graph[edge[1]].add(edge[0]) 18 19 queue = [0] 20 node_set = set([]) 21 22 while queue: 23 key = queue.pop(0) 24 node_set.add(key) 25 for node in graph[key]: 26 if node not in node_set: 27 queue.append(node) 28 29 return len(node_set) == n
17.5.31二刷
if len(edges) != n - 1:
return False
這個條件非常重要,排除連通但是有環的情況。接下來只需要檢查是不是每個節點都visited了

1 class Solution: 2 # @param {int} n an integer 3 # @param {int[][]} edges a list of undirected edges 4 # @return {boolean} true if it's a valid tree, or false 5 def validTree(self, n, edges): 6 # Write your code here 7 if len(edges) != n - 1: 8 return False 9 d = {} 10 v = [0] * n 11 for i in range(n): 12 d[i] = set([]) 13 14 for e in edges: 15 d[e[0]].add(e[1]) 16 d[e[1]].add(e[0]) 17 18 queue = [0] 19 v[0] = 1 20 while queue: 21 p = queue.pop(0) 22 for pp in d[p]: 23 if v[pp] == 0: 24 v[pp] = 1 25 queue.append(pp) 26 return sum(v) == n
-------------------------------------------------------------------------
242.convert-binary-tree-to-linked-lists-by-depth
給一棵二叉樹,設計一個算法為每一層的節點建立一個鏈表。也就是說,如果一棵二叉樹有D
層,那么你需要創建D條鏈表。

1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 this.val = val 6 this.left, this.right = None, None 7 Definition for singly-linked list. 8 class ListNode: 9 def __init__(self, x): 10 self.val = x 11 self.next = None 12 """ 13 class Solution: 14 # @param {TreeNode} root the root of binary tree 15 # @return {ListNode[]} a lists of linked list 16 def binaryTreeToLists(self, root): 17 # Write your code here 18 # bfs 19 results = [] 20 if not root: 21 return [] 22 queue = [root] 23 while queue: 24 # bfs for each level 25 size = len(queue) 26 # header for a linked list 27 header = ListNode( -1) 28 result = header 29 for i in range(size): 30 ele = queue.pop(0) 31 result.next = ListNode(ele.val) 32 result = result.next 33 if ele.left: 34 queue.append(ele.left) 35 if ele.right: 36 queue.append(ele.right) 37 results.append(header.next) 38 return results 39
17.5.31二刷

1 """ 2 Definition of TreeNode: 3 class TreeNode: 4 def __init__(self, val): 5 this.val = val 6 this.left, this.right = None, None 7 Definition for singly-linked list. 8 class ListNode: 9 def __init__(self, x): 10 self.val = x 11 self.next = None 12 """ 13 class Solution: 14 # @param {TreeNode} root the root of binary tree 15 # @return {ListNode[]} a lists of linked list 16 def binaryTreeToLists(self, root): 17 # Write your code here 18 level = [] 19 result = [] 20 if not root: 21 return result 22 queue = [root] 23 while queue: 24 size = len(queue) 25 tmp = [] 26 for i in range(size): 27 tn = queue.pop(0) 28 tmp.append(tn.val) 29 if tn.left: 30 queue.append(tn.left) 31 if tn.right: 32 queue.append(tn.right) 33 level.append(tmp) 34 35 for l in level: 36 head = ListNode(0) 37 cur = head 38 for i in l: 39 cur.next = ListNode(i) 40 cur = cur.next 41 result.append(head.next) 42 43 return result 44
-------------------------------------------------------------------------
624.remove-substrings
Given a string s
and a set of n
substrings. You are supposed to remove every instance of those n substrings from s so that s is of the minimum length and output this minimum length.

1 class Solution: 2 # @param {string} s a string 3 # @param {set} dict a set of n substrings 4 # @return {int} the minimum length 5 def minLength(self, s, dict): 6 # Write your code here 7 if not s: 8 return 0 9 queue = [s] 10 visited = set([]) 11 min_len = sys.maxint 12 while queue: 13 ele = queue.pop(0) 14 for string in dict: 15 found = ele.find(string) 16 # to find all the string in ele 17 while found != -1: 18 new_s = ele[:found] + ele[found + len(string):] 19 if new_s not in visited: 20 visited.add(new_s) 21 queue.append(new_s) 22 if len(new_s) < min_len: 23 min_len = len(new_s) 24 found = ele.find(string, found + 1) 25 return min_len 26
17.5.31二刷
注意while found != -1:
要將字符串中刪除子串的所有可能性嘗試一遍,比如"abcabd", ["ab","abcd"] 按"ab"刪除出兩個子串"cabd","abcd"

1 class Solution: 2 # @param {string} s a string 3 # @param {set} dict a set of n substrings 4 # @return {int} the minimum length 5 def minLength(self, s, dict): 6 # Write your code here 7 if not s: 8 return 0 9 queue = [s] 10 visited = set([]) 11 min_len = len(s) 12 while queue: 13 ele = queue.pop(0) 14 for string in dict: 15 found = ele.find(string) 16 # to find all the string in ele 17 while found != -1: 18 new_s = ele[:found] + ele[found + len(string):] 19 if new_s not in visited: 20 visited.add(new_s) 21 queue.append(new_s) 22 if len(new_s) < min_len: 23 min_len = len(new_s) 24 found = ele.find(string, found + 1) 25 return min_len
-------------------------------------------------------------------------
137.clone-graph
克隆一張無向圖,圖中的每個節點包含一個 label
和一個列表 neighbors
。

1 # Definition for a undirected graph node 2 # class UndirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 class Solution: 7 # @param node, a undirected graph node 8 # @return a undirected graph node 9 def __init__(self): 10 self.dict = {} 11 12 def cloneGraph(self, node): 13 # write your code here 14 if not node: 15 return None 16 nodes = self.bfs(node) 17 18 map_new_node = {} 19 for n in nodes: 20 map_new_node[n] = UndirectedGraphNode(n.label) 21 22 for n in nodes: 23 for l in n.neighbors: 24 map_new_node[n].neighbors.append(map_new_node[l]) 25 26 return map_new_node[node] 27 28 def bfs(self, node): 29 result = [] 30 if not node: 31 return result 32 33 queue = [node] 34 node_set = set([]) 35 while queue: 36 37 n = queue.pop(0) 38 if n in node_set: 39 continue 40 result.append(n) 41 node_set.add(n) 42 for l in n.neighbors: 43 queue.append(l) 44 45 return result
17.5.31二刷

1 # Definition for a undirected graph node 2 # class UndirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 class Solution: 7 # @param node, a undirected graph node 8 # @return a undirected graph node 9 def __init__(self): 10 self.dict = {} 11 12 def cloneGraph(self, node): 13 # write your code here 14 if not node: 15 return 16 17 self.dict[node.label] = UndirectedGraphNode(node.label) 18 queue = [node] 19 20 while queue: 21 n = queue.pop(0) 22 for nn in n.neighbors: 23 if nn.label not in self.dict: 24 queue.append(nn) 25 self.dict[nn.label] = UndirectedGraphNode(nn.label) 26 self.dict[n.label].neighbors.append(self.dict[nn.label]) 27 28 29 return self.dict[node.label]
-------------------------------------------------------------------------
531.six-degrees
現在給你一個友誼關系,查詢兩個人可以通過幾步相連,如果不相連返回 -1

1 # Definition for Undirected graph node 2 # class UndirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 7 class Solution: 8 ''' 9 @param {UndirectedGraphNode[]} graph a list of Undirected graph node 10 @param {UndirectedGraphNode} s, t two Undirected graph nodes 11 @return {int} an integer 12 ''' 13 def sixDegrees(self, graph, s, t): 14 # Write your code here 15 if not graph or not s or not t: 16 return -1 17 18 queue = [s] 19 steps = 0 20 visited = set([s]) 21 22 while queue: 23 size = len(queue) 24 for i in range(size): 25 node = queue.pop(0) 26 if node == t: 27 return steps 28 for neighbor in node.neighbors: 29 if neighbor not in visited: 30 queue.append(neighbor) 31 visited.add(neighbor) 32 steps += 1 33 return -1
17.5.31二刷

1 # Definition for Undirected graph node 2 # class UndirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 7 class Solution: 8 ''' 9 @param {UndirectedGraphNode[]} graph a list of Undirected graph node 10 @param {UndirectedGraphNode} s, t two Undirected graph nodes 11 @return {int} an integer 12 ''' 13 def sixDegrees(self, graph, s, t): 14 # Write your code here 15 if not graph or not s or not t: 16 return -1 17 18 queue = [s] 19 steps = 0 20 visited = set([s]) 21 22 while queue: 23 size = len(queue) 24 for i in range(size): 25 node = queue.pop(0) 26 if node == t: 27 return steps 28 for neighbor in node.neighbors: 29 if neighbor not in visited: 30 queue.append(neighbor) 31 visited.add(neighbor) 32 steps += 1 33 return -1
-------------------------------------------------------------------------
605.sequence-reconstruction
判斷是否序列 org
能唯一地由 seqs
重構得出. org
是一個由從1到n的正整數排列而成的序列,1 ≤ n ≤ 10^4。 重構表示組合成seqs
的一個最短的父序列 (意思是,一個最短的序列使得所有 seqs
里的序列都是它的子序列).
判斷是否有且僅有一個能從 seqs
重構出來的序列,並且這個序列是org
。
注意點:
拓撲排序,一個點只能讓一個next入隊
最后比較是否都找到了

1 class Solution: 2 # @param {int[]} org a permutation of the integers from 1 to n 3 # @param {int[][]} seqs a list of sequences 4 # @return {boolean} true if it can be reconstructed only one or false 5 def sequenceReconstruction(self, org, seqs): 6 # Write your code here 7 from collections import defaultdict 8 edges = defaultdict(list) 9 indegrees = defaultdict(int) 10 nodes = set() 11 for seq in seqs: 12 nodes |= set(seq) 13 for i in xrange(len(seq)): 14 if i == 0: 15 indegrees[seq[i]] += 0 16 if i < len(seq) - 1: 17 edges[seq[i]].append(seq[i + 1]) 18 indegrees[seq[i + 1]] += 1 19 20 cur = [k for k in indegrees if indegrees[k] == 0] 21 res = [] 22 23 while len(cur) == 1: 24 cur_node = cur.pop() 25 res.append(cur_node) 26 for node in edges[cur_node]: 27 indegrees[node] -= 1 28 if indegrees[node] == 0: 29 cur.append(node) 30 if len(cur) > 1: 31 return False 32 return len(res) == len(nodes) and res == org
17.6.8 二刷

1 class Solution: 2 # @param {int[]} org a permutation of the integers from 1 to n 3 # @param {int[][]} seqs a list of sequences 4 # @return {boolean} true if it can be reconstructed only one or false 5 def sequenceReconstruction(self, org, seqs): 6 # Write your code here 7 if not org and (not seqs or not seqs[0]): 8 return True 9 map = {} 10 queue = [] 11 rebulid = [] 12 for seq in seqs: 13 if seq: 14 map.setdefault(seq[0], {"pre":0, "next":set([])}) 15 for i in range(1, len(seq)): 16 map.setdefault(seq[i], {"pre":0, "next":set([])}) 17 if seq[i] not in map[seq[i - 1]]["next"]: 18 map[seq[i]]["pre"] += 1 19 map[seq[i - 1]]["next"].add(seq[i]) 20 21 for key in map: 22 if map[key]["pre"] == 0: 23 queue.append(key) 24 25 if len(queue) != 1: 26 return False 27 28 while queue: 29 node = queue.pop(0) 30 rebulid.append(node) 31 flag = False 32 for next in map[node]["next"]: 33 map[next]["pre"] -= 1 34 if map[next]["pre"] == 0: 35 if not flag: 36 flag = True 37 queue.append(next) 38 else: 39 return False 40 return rebulid == org
-------------------------------------------------------------------------
431.connected-component-in-undirected-graph
找出無向圖中所有的連通塊。
圖中的每個節點包含一個label屬性和一個鄰接點的列表。(一個無向圖的連通塊是一個子圖,其中任意兩個頂點通過路徑相連,且不與整個圖中的其它頂點相連。)

1 # Definition for a undirected graph node 2 # class UndirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 class Solution: 7 # @param {UndirectedGraphNode[]} nodes a array of undirected graph node 8 # @return {int[][]} a connected set of a undirected graph 9 def connectedSet(self, nodes): 10 # Write your code here 11 queue = [] 12 visited = set([]) 13 results = [] 14 15 for node in nodes: 16 if node not in visited: 17 visited.add(node) 18 queue.append(node) 19 result = [node.label] 20 while queue: 21 item = queue.pop(0) 22 for neighbor in item.neighbors: 23 if neighbor not in visited: 24 queue.append(neighbor) 25 visited.add(neighbor) 26 result.append(neighbor.label) 27 results.append(sorted(result)) 28 return results 29
17.6.8 二刷

1 # Definition for a undirected graph node 2 # class UndirectedGraphNode: 3 # def __init__(self, x): 4 # self.label = x 5 # self.neighbors = [] 6 class Solution: 7 # @param {UndirectedGraphNode[]} nodes a array of undirected graph node 8 # @return {int[][]} a connected set of a undirected graph 9 def connectedSet(self, nodes): 10 # Write your code here 11 result = [] 12 not_visited = set([]) 13 for n in nodes: 14 not_visited.add(n) 15 16 while not_visited: 17 next = None 18 for i in not_visited: 19 next = i 20 break 21 queue = [next] 22 not_visited.remove(next) 23 tmp = [] 24 while queue: 25 node = queue.pop(0) 26 tmp.append(node.label) 27 for n in node.neighbors: 28 if n in not_visited: 29 queue.append(n) 30 not_visited.remove(n) 31 result.append(sorted(tmp)) 32 return result 33
-------------------------------------------------------------------------