classSolution: deftwoSum(self, nums: List[int], target: int) -> List[int]: dict = {} for i, n inenumerate(nums): x = target - n if x indict: return [dict[x], i] else: dict[n] = i
暴力
两层循环,时间复杂度O(n^2) 注意:不能考虑重复元素
1 2 3 4 5 6 7
classSolution: deftwoSum(self, nums: List[int], target: int) -> List[int]: l = len(nums) for i inrange(l): for j inrange(i+1, l, 1): if nums[i] + nums[j] == target: return [i, j]
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
反向遍历POP
注意索引
1 2 3 4 5 6
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: for i inrange(len(nums)-1, -1, -1): if(nums[i] == val): nums.pop(i) returnlen(nums)
2
记录val值个数,一次循环,元素前移
1 2 3 4 5 6 7 8 9 10
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: k = 0 l = len(nums) for i, n inenumerate(nums): nums[i-k] = nums[i] if(n==val): k = k+1 return l-k
双指针
l为新数组索引,r为原数组索引。
1 2 3 4 5 6 7 8 9
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: l = 0 r = 0 for r inrange(len(nums)): if(nums[r]!=val): nums[l]=nums[r] l = l+1 return l
count & remove
1 2 3 4 5 6
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: a = nums.count(val) # 计算数组nums中val值的个数 for i inrange(a): nums.remove(val) returnlen(nums)
index & del
1 2 3 4 5
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: while val in nums: del nums[nums.index(val)] returnlen(nums)
classSolution: defsearch(self, nums: List[int], target: int) -> int: l, r = 0, len(nums)-1 while l <= r: m = (l+r)//2 if target == nums[m]: return m elif target>nums[m]: l = m + 1 else: r = m - 1 return -1
返回一个长度为 nums1.length 的数组 ans 作为答案,满足 ans[i] 是如上所述的 下一个更大元素 。
暴力
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defnextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: ans = [] for n in nums1: i = nums2.index(n) for j inrange(i, len(nums2)): if nums2[j] > n: ans.append(nums2[j]) break if j == len(nums2)-1: ans.append(-1) return ans
单调栈
从后往前遍历nums2,当栈顶元素比当前值小则出栈,保证栈顶为最近的大元素。
1 2 3 4 5 6 7 8 9 10
classSolution: defnextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]: res = {} st = [] for num inreversed(nums2): while st and num >= st[-1]: st.pop() res[num] = st[-1] if st else -1 st.append(num) return [res[num] for num in nums1]
classSolution: defminArray(self, numbers: List[int]) -> int: ans = numbers[-1] for i inrange(len(numbers)-1, -1, -1): if ans >= numbers[i]: ans = numbers[i] else: return ans return ans
二分
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defminArray(self, numbers: List[int]) -> int: l, r = 0, len(numbers) - 1 while l < r: m = (l + r) // 2 if numbers[m] < numbers[r] or numbers[m] < numbers[l]: r = m elif numbers[m] > numbers[r]: l = m + 1 else: returnmin(numbers[l:r]) return numbers[l]
classSolution: deffindContinuousSequence(self, target: int) -> List[List[int]]: res = [] for i inrange(1, target//2 + 1): s = 0 for j inrange(i, target): if s == target and j - i > 1: res.append(list(range(i, j))) elif s > target: break s += j return res
双指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: deffindContinuousSequence(self, target: int) -> List[List[int]]: l, r, s = 1, 2, 3 res = [] while l < r: if s == target: res.append(list(range(l, r + 1))) if s >= target: s -= l l += 1 else: r += 1 s += r return res
classSolution: defmaxSubArray(self, nums: List[int]) -> int: f = len(nums) * [0] ms = f[0] = nums[0] for i inrange(1, len(nums)): f[i] = f[i-1] + nums[i] if f[i-1]>0else nums[i] ms = ms if ms >= f[i] else f[i] return ms
计算索引 left 和 right (包含 left 和 right)之间的 nums 元素的 和 ,其中 left <= right 实现 NumArray 类:
NumArray(int[] nums) 使用数组 nums 初始化对象 int sumRange(int i, int j) 返回数组 nums 中索引 left 和 right 之间的元素的 总和 ,包含 left 和 right 两点(也就是 nums[left] + nums[left + 1] + … + nums[right] )
前缀和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classNumArray:
def__init__(self, nums: List[int]): self.pre = [0] * (len(nums) + 1) for i inrange(len(nums)): self.pre[i+1] = self.pre[i] + nums[i]
classSolution: defintersect(self, nums1: List[int], nums2: List[int]) -> List[int]: dic = (Counter(nums1) & Counter(nums2)) res = [] for i in dic.keys(): res += dic[i]*[i] return res
classSolution: defreverseString(self, s: List[str]) -> None: """ Do not return anything, modify s in-place instead. """ s.reverse()
切片
1 2 3 4 5 6
classSolution: defreverseString(self, s: List[str]) -> None: """ Do not return anything, modify s in-place instead. """ s[:] = s[::-1]
双指针
1 2 3 4 5 6 7 8 9 10 11
classSolution: defreverseString(self, s: List[str]) -> None: """ Do not return anything, modify s in-place instead. """ l = 0 r = len(s)-1 while l<r: s[l], s[r] = s[r], s[l] l += 1 r -= 1
classSolution: defreverseLeftWords(self, s: str, n: int) -> str: st = [] for i inrange(n, len(s)): st.append(s[i]) for i inrange(0, n): st.append(s[i]) return''.join(st)
用求余运算简化代码
1 2 3 4 5 6 7
classSolution: defreverseLeftWords(self, s: str, n: int) -> str: st = [] l = len(s) for i inrange(n, l + n): st.append(s[i % l]) return''.join(st)
给你一个字符串 sequence ,如果字符串 word 连续重复 k 次形成的字符串是 sequence 的一个子字符串,那么单词 word 的 重复值为 k 。单词 word 的 最大重复值 是单词 word 在 sequence 中最大的重复值。如果 word 不是 sequence 的子串,那么重复值 k 为 0 。
给你一个字符串 sequence 和 word ,请你返回 最大重复值 k 。
str.find()
1 2 3 4 5 6 7 8
classSolution: defmaxRepeating(self, sequence: str, word: str) -> int: res = len(sequence)//len(word) while res: if sequence.find(word * res) >= 0: return res res -= 1 return res
暴力
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defmaxRepeating(self, sequence: str, word: str) -> int: lw = len(word) ls = len(sequence) maxk = 0 for i inrange(ls): k = 0 while i+lw <= ls and sequence[i:i+lw] == word: k += 1 i += lw if k > maxk: maxk = k return maxk
1 2 3 4 5 6 7 8
classSolution: defmaxRepeating(self, sequence: str, word: str) -> int: res = 0 tmp = word while tmp in sequence: tmp += word res += 1 return res
如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?
注意看清:s是目标串,t是原串。
双指针
1 2 3 4 5 6 7 8 9 10 11
classSolution: defisSubsequence(self, s: str, t: str) -> bool: ifnot s: returnTrue p = 0 for w in t: if w == s[p]: p += 1 if p == len(s): returnTrue returnFalse
str.find()
1 2 3 4 5 6 7 8 9
classSolution: defisSubsequence(self, s: str, t: str) -> bool: i = 0 for w in s: i = t.find(w, i) if i == -1: returnFalse i += 1 returnTrue
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defreverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: ans = None while head isnotNone: p = head.next head.next = ans ans = head head = p return ans
递归
1 2 3 4 5 6 7 8 9 10 11 12 13
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defreverseList(self, head: Optional[ListNode]) -> Optional[ListNode]: ifnot head ornot head.next: return head last = self.reverseList(head.next) head.next.next = head head.next = None return last
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
哈希表
用一个集合来存储已经访问过的结点(不是val),遍历访问时,判断当前结点是否已经访问过。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None
classSolution: defhasCycle(self, head: Optional[ListNode]) -> bool: seen = set() while head: if head in seen: returnTrue seen.add(head) head = head.next returnFalse
快慢指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None
classSolution: defhasCycle(self, head: Optional[ListNode]) -> bool: if head: slow = fast = head while fast and fast.next: slow = slow.next fast = fast.next.next if slow == fast: returnTrue returnFalse
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None
classSolution: defgetKthFromEnd(self, head: ListNode, k: int) -> ListNode: slow = fast = head for i inrange(k): fast = fast.next while fast: slow = slow.next fast = fast.next return slow
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None
classSolution: defgetIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]: dic = set() p = headA while p: dic.add(p) p = p.next p = headB while p: if p in dic: return p p = p.next return p
双指针
$$ a+(b-c)=b+(a-c)=a+b-c $$
1 2 3 4 5 6 7 8 9 10 11 12 13
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None
给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
遍历一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defdeleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]: p = head while p and p.next: if p.val == p.next.val: p.next = p.next.next else: p = p.next return head
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defisPalindrome(self, head: Optional[ListNode]) -> bool: st = [] fast, slow = head, head while fast and fast.next: fast, slow = fast.next.next, slow.next while slow: st.append(slow.val) slow = slow.next p = head while st: if st.pop()!=p.val: returnFalse p = p.next returnTrue
翻转
1 2 3 4 5 6 7 8 9 10 11 12 13
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next classSolution: defisPalindrome(self, head: Optional[ListNode]) -> bool: st = [] p = head while p: st.append(p.val) p = p.next return st[::1]==st[::-1]
# 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
classSolution: defmaxDepth(self, root: Optional[TreeNode]) -> int: depth = 0 if root: q = collections.deque() q.append(root) whilelen(q): depth += 1 for i inrange(len(q)): tmp = q.popleft() if tmp.left: q.append(tmp.left) if tmp.right: q.append(tmp.right) return depth
# 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 classSolution: defminDepth(self, root: Optional[TreeNode]) -> int: if root: if root.right and root.left: returnmin(self.minDepth(root.left), self.minDepth(root.right)) + 1 if root.right: return self.minDepth(root.right) + 1 if root.left: return self.minDepth(root.left) + 1 # 遇到叶子结点则返回 return1 return0
# Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None
classSolution: deflevelOrder(self, root: TreeNode) -> List[List[int]]: res = [] if root: que = collections.deque() que.append(root) while que: lay = [] for i inrange(len(que)): p = que.popleft() lay.append(p.val) if p.left: que.append(p.left) if p.right: que.append(p.right) res.append(lay) return res return res
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 给定一个罗马数字,将其转换成整数。
字典
数组记录,小数在大数前面,则小数取负,最后全部相加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defromanToInt(self, s: str) -> int: dict = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000} st = [0] top = ans = 0 for i in s: st.append(dict[i]) # 小数在大数前面,则小数取负 if(dict[i]>st[top]): st[top] = - st[top] top += 1 for i in st: ans += i return ans
classSolution: defmaxProfit(self, prices: List[int]) -> int: res = 0 for i inrange(0, len(prices)-1): for j inrange(i+1, len(prices)): res = max(prices[j]-prices[i], res) return res
defpop(self) -> int: tmp = self.st[-1] del self.st[-1] return tmp
deftop(self) -> int: return self.st[-1]
defempty(self) -> bool: returnlen(self.st)==0
# Your MyStack object will be instantiated and called as such: # obj = MyStack() # obj.push(x) # param_2 = obj.pop() # param_3 = obj.top() # param_4 = obj.empty()
# Your MyStack object will be instantiated and called as such: # obj = MyStack() # obj.push(x) # param_2 = obj.pop() # param_3 = obj.top() # param_4 = obj.empty()
# Your MyStack object will be instantiated and called as such: # obj = MyStack() # obj.push(x) # param_2 = obj.pop() # param_3 = obj.top() # param_4 = obj.empty()
# Your MinStack object will be instantiated and called as such: # obj = MinStack() # obj.push(x) # obj.pop() # param_3 = obj.top() # param_4 = obj.min()
classSolution: defisPalindrome(self, x: int) -> bool: if x<0: returnFalse else: cur = 0 num = x while(num>0): cur = cur*10 + num%10 num = num//10 return cur == x
classSolution: defmySqrt(self, x: int) -> int: if x == 0: return0 x0, x1 = float(x), float('inf') while x1-x0 > 1e-7: x0, x1 = (x0 + x / x0) / 2, x0 returnint(x0)
二分查找
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: defmySqrt(self, x: int) -> int: l, r, ans = 0, x, -1 while l<=r: m = (l+r)//2 if m**2 <= x: l = m + 1 ans = m else: r = m - 1 return ans
math
1 2 3 4 5 6
classSolution: defmySqrt(self, x: int) -> int: if x==0: return0 ans = int(math.exp(0.5 * math.log(x))) return ans+1if (ans+1)**2<=x else ans
classSolution: defreachNumber(self, target: int) -> int: target = abs(target) k = 0 while target > 0: k += 1 target -= k return k if target % 2 == 0else k + 1 + k % 2#多走两步必奇数
classSolution: defmajorityElement(self, nums: List[int]) -> List[int]: vote1 = 0 vote2 = 0 candidate1 = None candidate2 = None for num in nums: if num==candidate1: vote1 += 1 elif num==candidate2: vote2 += 1 elif vote1==0: vote1 = 1 candidate1 = num elif vote2==0: vote2 = 1 candidate2 = num else: vote1 -= 1 vote2 -= 1 res = [] cnt1, cnt2 = 0, 0 for num in nums: if vote1>0and num==candidate1: cnt1 += 1 elif vote2>0and num==candidate2: cnt2 += 1 if cnt1 > len(nums)//3: res.append(candidate1) if cnt2 > len(nums)//3: res.append(candidate2) return res
哈希字典
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defmajorityElement(self, nums: List[int]) -> List[int]: dic = {} res = [] for num in nums: if num in dic: dic[num] += 1 else: dic[num] = 1 for i in dic.keys(): if dic[i] > len(nums)//3 : res.append(i) return res
classSolution: defbestCoordinate(self, towers: List[List[int]], radius: int) -> List[int]: dis = lambda s1, s2 : ((s1[0] - s2[0]) ** 2 + (s1[1] - s2[1]) ** 2) ** 0.5 maxq = 0 res = [0, 0] for x inrange(51): for y inrange(51): q = 0 for t in towers: d = dis([x, y], t) if d <= radius: q += floor(t[2] / (1 + d)) if q > maxq: maxq, res = q, [x, y] return res