Leetcode 刷题记录
0417
153. 寻找旋转排序数组中的最小值
二分查找,要注意边界。
这个数组有个性质,可以划分成两段升序,而且左半部分都>nums[-1],右半部分都<=nums[-1]。
二分mid查找,如果nums[mid]>nums[-1], 说明mid处于左半段,答案在[mid+1, r]之间;如果nums[mid]<=nums[-1], 说明mid处于右半段,答案在[l, mid]之间。
class Solution:
def findMin(self, nums: List[int]) -> int:
l, r = 0, len(nums) - 1
while l < r:
mid = (l + r) // 2
if nums[mid] > nums[len(nums)-1]:
l = mid + 1
else:
r = mid
# print(l, r)
return nums[l]
208. 实现 Trie (前缀树)
数据结构乱写。
class Node:
def __init__(self):
self.sons = {}
self.end = False
class Trie:
def __init__(self):
self.root = Node()
def insert(self, word: str) -> None:
tmp = self.root
for x in word:
if x in tmp.sons:
tmp = tmp.sons[x]
else:
tmp.sons[x] = Node()
tmp = tmp.sons[x]
tmp.end = True
def search(self, word: str) -> bool:
# print(self.root.sons)
tmp = self.root
for x in word:
if x in tmp.sons:
tmp = tmp.sons[x]
else:
return False
return tmp.end
def startsWith(self, prefix: str) -> bool:
tmp = self.root
for x in prefix:
if x in tmp.sons:
tmp = tmp.sons[x]
else:
return False
return True
# Your Trie object will be instantiated and called as such:
# obj = Trie()
# obj.insert(word)
# param_2 = obj.search(word)
# param_3 = obj.startsWith(prefix)
101. 对称二叉树
递归,划分左右子数,左左和右右对称,左右和右左对称。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool:
# if (root.left == None) != (root.right == None):
# return False
return self.sym(root.left, root.right)
def sym(self, left, right):
if left == None and right == None:
return True
if left == None or right == None:
return False
if left.val != right.val:
return False
return self.sym(left.left, right.right) and self.sym(left.right, right.left)
35. 搜索插入位置
二分查找
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
l, r = 0, len(nums) - 1
while l < r:
mid = (l + r + 1) // 2
# print(l, r, mid)
if nums[mid] == target:
return mid
if nums[mid] > target:
r = mid - 1
else:
l = mid
if nums[l] < target:
return l + 1
return 0
128. 最长连续序列
dict默认是个哈希表吗?
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
h = {}
for i, x in enumerate(nums):
h[x] = i
ans = 0
for i, x in enumerate(nums):
if x-1 not in h:
tmp = x
while tmp+1 in h:
tmp = tmp+1
ans = max(ans, tmp-x+1)
return ans
42. 接雨水
竟然是困难题目吗?
针对某一列分析,它能存储多少高的水柱?左边找到最高的柱子,右边找到最高的柱子,他的水柱最高能到这两者值的min值,如果这个值>该位置本身的高度,就有差值这么多的水了。
class Solution:
def trap(self, height: List[int]) -> int:
left = 0
ans = 0
lheight = []
max_height = 0
for i, x in enumerate(height):
lheight.append(max_height)
max_height = max(max_height, x)
max_height = 0
for i, x in enumerate(reversed(height)):
max_height = max(max_height, x)
lh = lheight[len(height)-1 - i]
h = min(lh, max_height)
# print(len(height)-1 - i, h, lh, max_height)
if x < h:
ans += h - x
return ans
169. 多数元素
虽然是一道简单题目,但是On做法需要思考一下。
其实就是多数元素跟别人1:1抵消之后,最后还能存在。
class Solution:
def majorityElement(self, nums: List[int]) -> int:
count = 0
ans = nums[0]
for x in nums:
if count == 0:
ans = x
if x == ans:
count += 1
else:
count -= 1
return ans
39. 组合总和
数据很小,就乱搞了,我爱递归。
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
print(candidates, target)
if target == 0:
return [[]]
if candidates == []:
return []
ans = []
for i in range(0, target // candidates[0] + 1):
tmp = self.combinationSum(candidates[1:], target - candidates[0] * i)
for l in tmp:
ans.append([candidates[0]] * i + l)
print(candidates, target, ans)
return ans
64. 最小路径和
二维DP。
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
inf = 1e9
f = [[inf] * len(grid[0]) for _ in range(len(grid))]
f[0][0] = grid[0][0]
for i in range(len(grid)):
for j in range(len(grid[0])):
if i > 0:
f[i][j] = min(f[i][j], f[i-1][j] + grid[i][j])
if j > 0:
f[i][j] = min(f[i][j], f[i][j-1] + grid[i][j])
return f[len(grid)-1][len(grid[0])-1]
累了,今天到此为止吧。明天看下八股。