刷题

leetcode

1.两数之和

#哈希表
class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:hashtable = dict()for i, item in enumerate(nums):if target-item in hashtable:return [hashtable[target-item],i]hashtable[item] = ireturn []

#yy暴力
class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:for i in nums:tmp = nums[nums.index(i)+1:]if target-i in tmp:return [nums.index(i), nums.index(i)+tmp.index(target-i)+1]

8.回文数

#数学解法
class Solution:def isPalindrome(self, x: int) -> bool:if x>=0 and x<10 :return Trueif x!=0 and x%10 == 0: #前面已经判断了,可以不判断0return Falseif x<0:return Falserx=0while(rx<x):rx = 10*rx + x%10x = x//10print("rx, x", rx,x)if rx ==x:return Trueif rx>x and rx//10==x:return Trueelse:return False
#字符串反转
class Solution(object):def isPalindrome(self, x):""":type x: int:rtype: bool"""xm = str(x)xR = ''.join(reversed(xm))return xm==xR

2022/1/19

704.二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

class Solution(object):def search(self, nums, target):""":type nums: List[int]:type target: int:rtype: int"""length = len(nums)high = length-1low = 0while low<=high :mid = (low+high)/2if nums[mid]==target:return midelif nums[mid]>target:high = mid-1elif nums[mid]<target:low = mid+1return -1

278.第一个错误的版本

class Solution:def firstBadVersion(self, n):""":type n: int:rtype: int"""l, r = 1, nwhile l <= r: # 重点一:l <= rmid = (l+r)//2if isBadVersion(mid):r = mid - 1else:l = mid + 1return l # 重点二:return l

2022/1/20

977.有序数组的平方

class Solution:def sortedSquares(self, nums: List[int]) -> List[int]:neg,length = -1, len(nums)for i, num in enumerate(nums):if num<0:neg = ians = list()p,q = neg,neg+1while p>=0 or q<length:if p<0:ans.append(nums[q]*nums[ q])q+=1elif q==length:ans.append(nums[p]*nums[p])p-=1elif nums[p]*nums[p] <= nums[q]*nums[q]:ans.append(nums[p]*nums[p])p-=1elif nums[p]*nums[p] > nums[q]*nums[q]:ans.append(nums[q]*nums[q])q+=1return ans

189.轮转数组

#复制数组
class Solution:def rotate(self, nums: List[int], k: int) -> None:"""Do not return anything, modify nums in-place instead."""tmp = nums[0]length = len(nums)ans = list(nums)for i in range(length):nums[(i+k)%length] = ans[i]
class Solution:def rotate(self, nums: List[int], k: int) -> None:"""Do not return anything, modify nums in-place instead."""        n = len(nums)k %= nnums.reverse()nums[:k] = list(reversed(nums[:k]))nums[k:] = list(reversed(nums[k:]))

2022/1/21

283.移动零

#计数覆盖
class Solution:def moveZeroes(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""h, nonzero, move = 0, 0, 0length = len(nums)while nonzero<length:if nums[nonzero]!=0:nums[h]=nums[nonzero] h+=1nonzero+=1for i in range(h, length):nums[i]=0
#双指针
class Solution:def moveZeroes(self, nums: List[int]) -> None:n = len(nums)left = right = 0while right < n:if nums[right] != 0:nums[left], nums[right] = nums[right], nums[left]left += 1right += 1print(nums)

167. 两数之和 II - 输入有序数组

class Solution:def twoSum(self, numbers: List[int], target: int) -> List[int]:length = len(numbers)left,right = 0, length-1while left < right:total = numbers[left]+numbers[right]if total == target:return [left+1, right+1]elif total < target:left+=1elif total > target:right-=1return [-1,-1]

2022\1\22

#列表切片
class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""s[:]=s[::-1]#s[::-1]表示反转s中的元素
#s[:]表示数组中所有子模块
#s[:]=s[::-1]表示将原数组反转后赋值给s中每一个对应的位置
#s=s[::-1]表示将s反转后赋值给新的对象s(可以通过id函数查看内存地址),与题意原地修改不符。
代码作者:yim-6
链接:https://leetcode-cn.com/problems/reverse-string/solution/python3-liang-chong-fang-fa-shi-xian-fan-zhuan-zi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#双指针
class Solution:def reverseString(self, s: List[str]) -> None:"""Do not return anything, modify s in-place instead."""length = len(s)left, right =0, length-1while left < right:tmp = s[left]s[left] = s[right]s[right] = tmpleft+=1right-=1

557. 反转字符串中的单词 III

#双指针
class Solution:def reverseWords(self, s: str) -> str:ans = ''words = s.split(' ')for idx, word in enumerate(words):rs = ''.join(reversed(word))ans = ans + rsprint(idx)if idx!=len(words)-1:ans = ans + ' 'return ans
class Solution(object):def reverseWords(self, s):return " ".join(word[::-1] for word in s.split(" "))作者:swants
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/solution/python-fan-zhuan-zi-fu-chuan-zhong-dan-ci-si-lu-xi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2022/1/24

876. 链表的中间结点

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def middleNode(self, head: ListNode) -> ListNode:slow, fast = head, headwhile fast != None:if fast.next == None:return slowif fast.next == None:return slow.nextslow = slow.nextfast = fast.next.nextreturn slow
class Solution:def middleNode(self, head: ListNode) -> ListNode:slow = fast = headwhile fast and fast.next:slow = slow.nextfast = fast.next.nextreturn slow作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/middle-of-the-linked-list/solution/lian-biao-de-zhong-jian-jie-dian-by-leetcode-solut/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

567. 字符串的排列

class Solution:def checkInclusion(self, s1: str, s2: str) -> bool:counter1 = collections.Counter(s1)n1, n2 = len(s1), len(s2)left = 0right = left + n1while right<=n2 and left <=n2:counter2 = collections.Counter(s2[left:right])if counter1 == counter2:return Trueleft+=1right+=1return False
class Solution(object):def checkInclusion(self, s1, s2):""":type s1: str:type s2: str:rtype: bool"""# 统计 s1 中每个字符出现的次数counter1 = collections.Counter(s1)N = len(s2)# 定义滑动窗口的范围是 [left, right],闭区间,长度与s1相等left = 0right = len(s1) - 1# 统计窗口s2[left, right - 1]内的元素出现的次数counter2 = collections.Counter(s2[0:right])while right < N:# 把 right 位置的元素放到 counter2 中counter2[s2[right]] += 1# 如果滑动窗口内各个元素出现的次数跟 s1 的元素出现次数完全一致,返回 Trueif counter1 == counter2:return True# 窗口向右移动前,把当前 left 位置的元素出现次数 - 1counter2[s2[left]] -= 1# 如果当前 left 位置的元素出现次数为 0, 需要从字典中删除,否则这个出现次数为 0 的元素会影响两 counter 之间的比较if counter2[s2[left]] == 0:del counter2[s2[left]]# 窗口向右移动left += 1right += 1return False# 作者:fuxuemingzhu
# 链接:https://leetcode-cn.com/problems/permutation-in-string/solution/zhu-shi-chao-xiang-xi-de-hua-dong-chuang-rc7d/
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2022/1/25 (广度优先搜索/宽度优先搜索)

733. 图像渲染

#广度优先
class Solution:def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]:currColor = image[sr][sc]if currColor == newColor:return imagen, m = len(image), len(image[0])que = collections.deque([(sr, sc)])image[sr][sc] = newColorwhile que:x, y = que.popleft()for mx, my in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:if 0 <= mx < n and 0 <= my < m and image[mx][my] == currColor:que.append((mx, my))image[mx][my] = newColorreturn image
#深度优先搜索
class Solution:def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]:n, m = len(image), len(image[0])currColor = image[sr][sc]def dfs(x: int, y: int):if image[x][y] == currColor:image[x][y] = newColorfor mx, my in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:if 0 <= mx < n and 0 <= my < m and image[mx][my] == currColor:dfs(mx, my)if currColor != newColor:dfs(sr, sc)return image作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/flood-fill/solution/tu-xiang-xuan-ran-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

695. 岛屿的最大面积

#深度优先搜索
class Solution:def dfs(self, grid, cur_i,cur_j):if cur_i < 0 or cur_j <0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j]==0 :return 0grid[cur_i][cur_j]=0ans = 1for di, dj in [[0, 1], [0, -1], [1, 0], [-1, 0]]:next_i, next_j = cur_i + di, cur_j + djans += self.dfs(grid, next_i, next_j) return ansdef maxAreaOfIsland(self, grid: List[List[int]]) -> int:ans = 0for i, l in enumerate(grid):for j, n in enumerate(l):ans = max(self.dfs(grid, i, j), ans)return ans

2022/1/26

617. 合并二叉树

# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:if not root1:return root2if not root2:return root1merged = TreeNode(root1.val+root2.val)merged.left = self.mergeTrees(root1.left, root2.left)merged.right = self.mergeTrees(root1.right, root2.right)return merged

116. 填充每个节点的下一个右侧节点指针

层次遍历基于广度优先搜索,它与广度优先搜索的不同之处在于,广度优先搜索每次只会取出一个节点来拓展,而层次遍历每次将队列中的所有元素都拿出来拓展,这样能保证每次从队列中拿出来遍历的元素都是属于同一层的,因此我们可以在遍历的过程中修改每个节点的 next 指针,同时拓展下一层的新队列。

import collections class Solution:def connect(self, root: 'Node') -> 'Node':if not root:return root# 初始化队列同时将第一层节点加入队列中,即根节点Q = collections.deque([root])# 外层的 while 循环迭代的是层数while Q:# 记录当前队列大小size = len(Q)# 遍历这一层的所有节点for i in range(size):# 从队首取出元素node = Q.popleft()# 连接if i < size - 1:node.next = Q[0]# 拓展下一层节点if node.left:Q.append(node.left)if node.right:Q.append(node.right)# 返回根节点return root#作者:LeetCode-Solution
#链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/tian-chong-mei-ge-jie-dian-de-xia-yi-ge-you-ce-2-4/
#来源:力扣(LeetCode)
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2022/1/27

广度优先搜索和宽度优先搜索

542. 01 矩阵

class Solution:def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:m, n = len(mat), len(mat[0])dist = [[0] * n for _ in range(m)]zeroes_pos = [(i, j) for i in range(m) for j in range(n) if mat[i][j]==0]q = collections.deque(zeroes_pos)seen = set(zeroes_pos)while q:i, j = q.popleft()for ni, nj in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in seen:dist[ni][nj] = dist[i][j]+1q.append((ni, nj))seen.add((ni, nj))return dist

994. 腐烂的橘子

class Solution:def orangesRotting(self, grid: List[List[int]]) -> int:R, C = len(grid), len(grid[0])queue = collections.deque()for r, row in enumerate(grid):for c, val in enumerate(row):if val == 2:queue.append((r,c,0))def neighbors(r, c)->(int, int):for nr, nc in [(r+1, c), (r-1, c), (r, c-1), (r,c+1)]:if 0<=nr<R and 0<=nc<C:yield nr, ncd=0           while queue:r, c, d = queue.popleft()for nr, nc in neighbors(r,c):if grid[nr][nc] == 1:grid[nr][nc] = 2queue.append((nr, nc, d+1))if any(1 in row for row in grid):return -1return d

2022/1/28

递归\回溯

21. 合并两个有序链表

#迭代写法
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def mergeTwoLists(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:prehead = ListNode(-1)prev = preheadwhile l1 and l2:if l1.val <= l2.val:prev.next = l1l1 = l1.nextprev = prev.nextelse:prev.next = l2l2 = l2.nextprev = prev.nextprev.next = l1 if l1 is not None else l2return prehead.next
#递归写法
class Solution:def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:if l1 is None:return l2elif l2 is None:return l1elif l1.val < l2.val:l1.next = self.mergeTwoLists(l1.next, l2)return l1else:l2.next = self.mergeTwoLists(l1, l2.next)return l2作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

206. 反转链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reverseList(self, head: ListNode) -> ListNode:st = collections.deque()while head:st.append(head.val)head = head.nextprehead = ListNode(-1)prev = preheadfor i in range(len(st)):tmp = ListNode(st.pop()) prev.next = tmpprev = prev.nextreturn prehead.next

剑指offer

2022/2/23

栈与队列(简单)

剑指 Offer 09. 用两个栈实现队列

class CQueue:def __init__(self):self.A, self.B = [],[]def appendTail(self, value: int) -> None:self.A.append(value)def deleteHead(self) -> int:if self.B:return self.B.pop()if not self.A:return -1else:while self.A:self.B.append(self.A.pop())return self.B.pop()# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()

剑指 Offer 30. 包含min函数的栈

class MinStack:def __init__(self):"""initialize your data structure here."""self.A = []self.B = []def push(self, x: int) -> None:self.A.append(x)if not self.B or self.B[-1]>=x:self.B.append(x)def pop(self) -> None:if self.A.pop() == self.B[-1]:self.B.pop()def top(self) -> int:return self.A[-1]def min(self) -> int:return self.B[-1]# 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()

链表(简单)

2022/2/24

剑指 Offer 06. 从尾到头打印链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def reversePrint(self, head: ListNode) -> List[int]:stack = []while head:stack.append(head.val)head = head.nextreturn stack[::-1]作者:jyd
链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/solution/mian-shi-ti-06-cong-wei-dao-tou-da-yin-lian-biao-d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。class Solution:def reversePrint(self, head: ListNode) -> List[int]:self.A, self.res = [], []p = headwhile p:self.A.append(p.val)p = p.nextwhile self.A:self.res.append(self.A.pop())return  self.res

剑指 Offer 24. 反转链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def reverseList(self, head: ListNode) -> ListNode:pre, p = None, head#pre设为None,就可以一并处理了while p:after = p.nextp.next = prepre = pp = afterreturn pre

*剑指 Offer 35. 复杂链表的复制

#哈希表法
"""
# Definition for a Node.
class Node:def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):self.val = int(x)self.next = nextself.random = random
"""
class Solution:def copyRandomList(self, head: 'Node') -> 'Node':if not head:return headdic = {}cur = headwhile cur:dic[cur] = Node(cur.val)#键是原链表节点,值是新链表节点cur = cur.nextcur = headwhile cur:dic[cur].next = dic.get(cur.next)#哈希表 get()返回指定键的值dic[cur].random = dic.get(cur.random)cur = cur.nextreturn dic[head]
#拼接+拆分
class Solution:def copyRandomList(self, head: 'Node') -> 'Node':if not head: returncur = head# 1. 复制各节点,并构建拼接链表while cur:tmp = Node(cur.val)tmp.next = cur.nextcur.next = tmpcur = tmp.next# 2. 构建各新节点的 random 指向cur = headwhile cur:if cur.random:cur.next.random = cur.random.nextcur = cur.next.next# 3. 拆分两链表cur = res = head.nextpre = headwhile cur.next:pre.next = pre.next.nextcur.next = cur.next.nextpre = pre.nextcur = cur.nextpre.next = None # 单独处理原链表尾节点return res      # 返回新链表头节点作者:jyd
链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/solution/jian-zhi-offer-35-fu-za-lian-biao-de-fu-zhi-ha-xi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

字符串(简单)

剑指 Offer 05. 替换空格

class Solution:def replaceSpace(self, s: str) -> str:res = []for c in s:if c == " ":res.append("%20")else:res.append(c)return "".join(res)

剑指 Offer 58 - II. 左旋转字符串

class Solution:def reverseLeftWords(self, s: str, n: int) -> str:A = []for c in s:A.append(c)for i in range(n):tmp = A.pop(0)A.append(tmp)return "".join(A)
#字符串切片
class Solution:def reverseLeftWords(self, s: str, n: int) -> str:res = []for i in range(n, len(s)):res.append(s[i])for i in range(n):res.append(s[i])return ''.join(res)作者:jyd
链接:https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/solution/mian-shi-ti-58-ii-zuo-xuan-zhuan-zi-fu-chuan-qie-p/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:def reverseLeftWords(self, s: str, n: int) -> str:return s[n:] + s[:n]作者:jyd
链接:https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/solution/mian-shi-ti-58-ii-zuo-xuan-zhuan-zi-fu-chuan-qie-p/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

查找算法(简单)

2022/2/26

剑指 Offer 03. 数组中重复的数字

class Solution:def findRepeatNumber(self, nums: List[int]) -> int:dic = {}for n in nums:if not dic.get(n): dic[n] = 1else:return n
class Solution:def findRepeatNumber(self, nums: [int]) -> int:dic = set()for num in nums:if num in dic: return numdic.add(num)return -1作者:jyd
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/mian-shi-ti-03-shu-zu-zhong-zhong-fu-de-shu-zi-yua/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 53 - I. 在排序数组中查找数字 I

class Solution:def search(self, nums: List[int], target: int) -> int:dic = {}for n in nums:if not dic.get(n):dic[n] = 1else:dic[n]+=1if dic.get(target):return dic.get(target)else:return 0
#找target 和 target-1的右边界相减
class Solution:def search(self, nums: [int], target: int) -> int:def helper(tar):i, j = 0, len(nums) - 1while i <= j:m = (i + j) // 2if nums[m] <= tar: i = m + 1else: j = m - 1return ireturn helper(target) - helper(target - 1)作者:jyd
链接:https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/solution/mian-shi-ti-53-i-zai-pai-xu-shu-zu-zhong-cha-zha-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 53 - II. 0~n-1中缺失的数字

class Solution:def missingNumber(self, nums: List[int]) -> int:i, j = 0, len(nums)if nums[i]:return 0if j-1 == nums[j-1]:return jwhile i<=j:mid = int((i+j)/2)if mid == nums[mid] and mid+1 <nums[mid+1]:return mid+1elif mid < nums[mid]: j = mid-1elif mid == nums[mid]:i = mid+1
class Solution:def missingNumber(self, nums: List[int]) -> int:i, j = 0, len(nums) - 1while i <= j:m = (i + j) // 2if nums[m] == m: i = m + 1else: j = m - 1return i作者:jyd
链接:https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/solution/mian-shi-ti-53-ii-0n-1zhong-que-shi-de-shu-zi-er-f/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

查找算法(中等)

2022/2/27

* 剑指 Offer 04. 二维数组中的查找

#从矩阵 matrix 左下角元素(索引设为 (i, j) )开始遍历,并与目标值对比:
#当matrix[i][j] > target时,执行i-- ,即消去第 i 行元素;
#当matrix[i][j] < target时,执行j++ ,即消去第 j 列元素;
#当matrix[i][j] = target时,返回true,代表找到目标值。class Solution:def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:i, j = len(matrix) - 1, 0while i >= 0 and j < len(matrix[0]):if matrix[i][j] > target: i -= 1elif matrix[i][j] < target: j += 1else: return Truereturn False作者:jyd
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/solution/mian-shi-ti-04-er-wei-shu-zu-zhong-de-cha-zhao-zuo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 11. 旋转数组的最小数字

class Solution:def minArray(self, numbers: [int]) -> int:i, j = 0, len(numbers) - 1while i < j:m = (i + j) // 2if numbers[m] > numbers[j]: i = m + 1elif numbers[m] < numbers[j]: j = melse: j -= 1return numbers[i]作者:jyd
链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/solution/mian-shi-ti-11-xuan-zhuan-shu-zu-de-zui-xiao-shu-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:def minArray(self, numbers: List[int]) -> int:i, j, min = 0, len(numbers)-1, numbers[-1]while i<len(numbers) and j>=0 and i<=j:print(i,j)if numbers[i] > numbers[j]:i+=1elif numbers[i] <= numbers[j]:min = numbers[i]if j>i:j-=1else :return minreturn min

剑指 Offer 50. 第一个只出现一次的字符

class Solution:def firstUniqChar(self, s: str) -> str:dic = {}for c in s:dic[c] = not c in dicfor c in s:if dic[c]: return creturn ' '作者:jyd
链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/mian-shi-ti-50-di-yi-ge-zhi-chu-xian-yi-ci-de-zi-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#有序哈希表
class Solution:def firstUniqChar(self, s: str) -> str:dic = collections.OrderedDict()for c in s:dic[c] = not c in dicfor k, v in dic.items():if v: return kreturn ' '作者:jyd
链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/mian-shi-ti-50-di-yi-ge-zhi-chu-xian-yi-ci-de-zi-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:def firstUniqChar(self, s: str) -> str:dic = {}for c in s:if not dic.get(c):dic[c] = 1else:dic[c] = dic[c]+1for c in s:if dic[c]:return creturn " "

搜索与回溯算法(简单)

2022/2/28

面试题32 - I. 从上到下打印二叉树

#队列
class Solution:def levelOrder(self, root: TreeNode) -> List[int]:if not root: return []res, queue = [], collections.deque()queue.append(root)while queue:node = queue.popleft()res.append(node.val)if node.left: queue.append(node.left)if node.right: queue.append(node.right)return res作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/solution/mian-shi-ti-32-i-cong-shang-dao-xia-da-yin-er-ch-4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 32 - II. 从上到下打印二叉树 II

复杂度分析:

时间复杂度 O(N) : N 为二叉树的节点数量,即 BFS 需循环 N 次。
空间复杂度 O(N) : 最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N)大小的额外空间。
class Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:if not root: return []res, queue = [], collections.deque()queue.append(root)while queue:tmp = []for _ in range(len(queue)):node = queue.popleft()tmp.append(node.val)if node.left: queue.append(node.left)if node.right: queue.append(node.right)res.append(tmp)return res作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/solution/mian-shi-ti-32-ii-cong-shang-dao-xia-da-yin-er-c-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:if not root:return []res, que = [], collections.deque()que.append(root)while que:tmp,out = [],[]while que:node = que.popleft()                 tmp.append(node.val)out.append(node)res.append(tmp)for node in out:if node.left: que.append(node.left)if node.right: que.append(node.right)return res

剑指 Offer 32 - III. 从上到下打印二叉树 III

class Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:if not root: return []res, deque = [], collections.deque([root])while deque:tmp = collections.deque()for _ in range(len(deque)):node = deque.popleft()if len(res) % 2: tmp.appendleft(node.val) # 偶数层 -> 队列头部else: tmp.append(node.val) # 奇数层 -> 队列尾部if node.left: deque.append(node.left)if node.right: deque.append(node.right)res.append(list(tmp))return res作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er--3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
方法三:层序遍历 + 倒序此方法的优点是只用列表即可,无需其他数据结构。偶数层倒序: 若 res 的长度为 奇数 ,说明当前是偶数层,则对 tmp 执行 倒序 操作。class Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:if not root: return []res, queue = [], collections.deque()queue.append(root)while queue:tmp = []for _ in range(len(queue)):node = queue.popleft()tmp.append(node.val)if node.left: queue.append(node.left)if node.right: queue.append(node.right)res.append(tmp[::-1] if len(res) % 2 else tmp)return res作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er--3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution:def levelOrder(self, root: TreeNode) -> List[List[int]]:if not root:return []res, que = [], collections.deque()que.append(root)flag = Falsewhile que:tmp = []  for i in range(len(que)):node = que.popleft()tmp.append(node.val)if node.left:que.append(node.left)if node.right:que.append(node.right)if flag:res.append(tmp[::-1])     else:res.append(tmp)flag = not flagreturn res

搜索与回溯(简单)

2020\03\01

* 递归-剑指 Offer 26. 树的子结构

recur(A, B) 函数:

1、终止条件:
当节点 B 为空:说明树 B已匹配完成(越过叶子节点),因此返回 true ;
当节点 A为空:说明已经越过树 A 叶子节点,即匹配失败,返回 false ;
当节点 A 和 B 的值不同:说明匹配失败,返回 false ;
2、 返回值:
判断 A 和 B 的左子节点是否相等,即 recur(A.left, B.left)
判断 A 和 B的右子节点是否相等,即 recur(A.right, B.right)

isSubStructure(A, B) 函数:

特例处理: 当 树 A为空 或 树 B 为空 时,直接返回 false ;
返回值: 若树 B是树 A 的子结构,则必满足以下三种情况之一,因此用或 || 连接;
以 节点 A 为根节点的子树 包含树 B ,对应 recur(A, B);
树 B 是 树 A左子树 的子结构,对应 isSubStructure(A.left, B);
树 B是 树 A右子树 的子结构,对应 isSubStructure(A.right, B);

class Solution:def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:def recur(A, B):if not B: return Trueif not A or A.val != B.val: return Falsereturn recur(A.left, B.left) and recur(A.right, B.right)return bool(A and B) and (recur(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B))作者:jyd
链接:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/solution/mian-shi-ti-26-shu-de-zi-jie-gou-xian-xu-bian-li-p/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

* 递归-剑指 Offer 27. 二叉树的镜像

方法一:递归法

根据二叉树镜像的定义,考虑递归遍历(dfs)二叉树,交换每个节点的左 / 右子节点,即可生成二叉树的镜像。

递归解析:

1.终止条件 当节点 root为空时(即越过叶节点),则返回 null ;

2.递推工作

1.初始化节点 tmp ,用于暂存 root 的左子节点;

2.开启递归 右子节点 mirrorTree(root.right),并将返回值作为 root的 左子节点 。

3.开启递归 左子节点 mirrorTree(tmp) ,并将返回值作为 root的 右子节点 。

3.返回值: 返回当前节点 root ;

Q: 为何需要暂存 root的左子节点?

A: 在递归右子节点 “root.left=mirrorTree(root.right);” 执行完毕后, root.left 的值已经发生改变,此时递归左子节点 mirrorTree(root.left)则会出问题。

#时间复杂度 O(N): 其中 N为二叉树的节点数量,建立二叉树镜像需要遍历树的所有节点,占用 O(N) 时间。
#空间复杂度 O(N) : 最差情况下(当二叉树退化为链表),递归时系统需使用 O(N) 大小的栈空间。class Solution:def mirrorTree(self, root: TreeNode) -> TreeNode:if not root: returntmp = root.leftroot.left = self.mirrorTree(root.right)root.right = self.mirrorTree(tmp)return root作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#Python 利用平行赋值的写法(即 a,b=b,a ),可省略暂存操作。其原理是先将等号右侧打包成元组 (b,a) ,再序列地分给等号左侧的 a,b 序列。class Solution:def mirrorTree(self, root: TreeNode) -> TreeNode:if not root: returnroot.left, root.right = self.mirrorTree(root.right), self.mirrorTree(root.left)return root作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法二:辅助栈(或队列)

利用栈(或队列)遍历树的所有节点 node,并交换每个 node 的左 / 右子节点。

算法流程:

1.特例处理: 当 root 为空时,直接返回 null;
2.初始化: 栈(或队列),本文用栈,并加入根节点 root 。
3.循环交换: 当栈 stack 为空时跳出;
1.出栈: 记为 node ;
2.添加子节点: 将 node 左和右子节点入栈;
3.交换: 交换 node 的左 / 右子节点。
4.返回值: 返回根节点 root 。

#复杂度分析:#  时间复杂度 O(N) : 其中 N 为二叉树的节点数量,建立二叉树镜像需要遍历树的所有节点,占用 O(N)时间。# 空间复杂度 O(N) : 最差情况下(右子树都为叶结点),栈 stack最多同时存储 2^(N+1) 个节点,占用 O(N) 额外空间。
class Solution:def mirrorTree(self, root: TreeNode) -> TreeNode:if not root: returnstack = [root]while stack:node = stack.pop()if node.left: stack.append(node.left)if node.right: stack.append(node.right)node.left, node.right = node.right, node.leftreturn root作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

* 递归-剑指 Offer 28. 对称的二叉树

对称二叉树定义: 对于树中 任意两个对称节点 L和 R ,一定有:

L.val=R.val :即此两对称节点值相等。
L.left.val=R.right.val :即 L 的 左子节点 和 R 的 右子节点 对称;
L.right.val=R.left.val :即 L 的 右子节点 和 R的 左子节点 对称。

算法流程:

isSymmetric(root) :

​ 特例处理: 若根节点 root 为空,则直接返回 true 。
​ 返回值: 即 recur(root.left, root.right) ;

recur(L, R)

终止条件:
当 L和 R 同时越过叶节点: 此树从顶至底的节点都对称,因此返回 true ;
当 L 或 R 中只有一个越过叶节点: 此树不对称,因此返回 false ;
当节点 L 值 ≠ 节点 R 值: 此树不对称,因此返回 falsee ;
递推工作:
判断两节点 L.lef 和 R.right是否对称,即 recur(L.left, R.right) ;
判断两节点 L.right 和 R.left 是否对称,即 recur(L.right, R.left) ;
返回值:

两对节点都对称时,才是对称树,因此用与逻辑符 && 连接。

class Solution:def isSymmetric(self, root: TreeNode) -> bool:def recur(L, R):if not L and not R: return Trueif not L or not R or L.val != R.val: return Falsereturn recur(L.left, R.right) and recur(L.right, R.left)return recur(root.left, root.right) if root else True作者:jyd
链接:https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/solution/mian-shi-ti-28-dui-cheng-de-er-cha-shu-di-gui-qing/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

动态规划(简单)

2022/03/02

*动态规划-剑指 Offer 10- I. 斐波那契数列

此类求 多少种可能性 的题目一般都有 递推性质 ,即 f(n)f(n)f(n) 和 f(n−1)f(n-1)f(n−1)…f(1)f(1)f(1) 之间是有联系的。

动态规划解析:

状态定义: 设 dp为一维数组,其中 dp[i]的值代表 斐波那契数列第 i 个数字 。
转移方程: dp[i+1]=dp[i]+dp[i−1] ,即对应数列定义 f(n+1)=f(n)+f(n−1);
初始状态: dp[0]=0, dp[1]=1,即初始化前两个数字;
返回值: dp[n],即斐波那契数列的第 n个数字。

class Solution:def fib(self, n: int) -> int:a, b = 0, 1for _ in range(n):a, b = b, a + breturn a % 1000000007作者:jyd
链接:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/solution/mian-shi-ti-10-i-fei-bo-na-qi-shu-lie-dong-tai-gui/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 10- II. 青蛙跳台阶问题

青蛙跳台阶问题: f(0)=1 , f(1)=1 , f(2)=2 ;#因为F(2)=2,所以f(0)=1
斐波那契数列问题: f(0)=0 , f(1)=1 , f(2)=1 。

class Solution:def numWays(self, n: int) -> int:a, b = 1, 1for _ in range(n):a, b = b, a + breturn a % 1000000007作者:jyd
链接:https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/solution/mian-shi-ti-10-ii-qing-wa-tiao-tai-jie-wen-ti-dong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 63. 股票的最大利润

动态规划解析

状态定义: 设动态规划列表 dp ,dp[i] 代表以 prices[i] 为结尾的子数组的最大利润(以下简称为 前 i 日的最大利润 )。
转移方程: 由于题目限定 “买卖该股票一次” ,因此前 i日最大利润 dp[i]等于前 i−1日最大利润 dp[i−1]和第 i 日卖出的最大利润中的最大值。

前i日最大利润=max⁡(前(i−1)日最大利润,第i日价格−前i日最低价格)

dp[i]=max⁡(dp[i−1],prices[i]−min⁡(prices[0:i]))

初始状态: dp[0]=0,即首日利润为 0 ;
返回值: dp[n−1] ,其中 n为 dp 列表长度。

class Solution:def maxProfit(self, prices: List[int]) -> int:cost, profit = float("+inf"), 0for price in prices:cost = min(cost, price)profit = max(profit, price - cost)return profit作者:jyd
链接:https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/solution/mian-shi-ti-63-gu-piao-de-zui-da-li-run-dong-tai-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

动态规划(中等)

2022/03/03

剑指 Offer 42. 连续子数组的最大和

转移方程: 若 dp[i−1]≤0 ,说明 dp[i−1] 对 dp[i]产生负贡献,即 dp[i−1]+nums[i] 还不如 nums[i] 本身大。

当 dp[i−1]>0 时:执行 dp[i]=dp[i−1]+nums[i];
当 dp[i−1]≤0 时:执行 dp[i]=nums[i] ;

初始状态: dp[0]=nums[0],即以 nums[0]结尾的连续子数组最大和为 nums[0] 。

返回值: 返回 dpdpdp 列表中的最大值,代表全局最大值。

class Solution:def maxSubArray(self, nums: List[int]) -> int:for i in range(1, len(nums)):nums[i] += max(nums[i - 1], 0)return max(nums)作者:jyd
链接:https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/solution/mian-shi-ti-42-lian-xu-zi-shu-zu-de-zui-da-he-do-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 47. 礼物的最大价值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qUcu37we-1648863192590)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220304214354903.png)]

class Solution:def maxValue(self, grid: List[List[int]]) -> int:for i in range(len(grid)):for j in range(len(grid[0])):if i == 0 and j == 0: continueif i == 0: grid[i][j] += grid[i][j - 1]elif j == 0: grid[i][j] += grid[i - 1][j]else: grid[i][j] += max(grid[i][j - 1], grid[i - 1][j])return grid[-1][-1]作者:jyd
链接:https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/solution/mian-shi-ti-47-li-wu-de-zui-da-jie-zhi-dong-tai-gu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

动态规划(中等)

2020/3/4

剑指 Offer 46. 把数字翻译成字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VoFP6reI-1648863192590)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220306152644582.png)]

class Solution:def translateNum(self, num: int) -> int:s = str(num)a = b = 1for i in range(2, len(s) + 1):a, b = (a + b if "10" <= s[i - 2:i] <= "25" else a), areturn a作者:jyd
链接:https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/solution/mian-shi-ti-46-ba-shu-zi-fan-yi-cheng-zi-fu-chua-6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 48. 最长不含重复字符的子字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QNcrxgKH-1648863192591)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220306164941644.png)]

#by Mallika
class Solution:def lengthOfLongestSubstring(self, s: str) -> int:if not len(s):return 0a, b = 1, 1for i in range(1, len(s)):if s[i] in s[i-a: i]:a = i-s[0: i].rfind(s[i])b = a if a>b else belse: a+=1b = a if a>b else breturn b
class Solution:def lengthOfLongestSubstring(self, s: str) -> int:dic = {}res = tmp = 0for j in range(len(s)):i = dic.get(s[j], -1) # 获取索引 idic[s[j]] = j # 更新哈希表tmp = tmp + 1 if tmp < j - i else j - i # dp[j - 1] -> dp[j]res = max(res, tmp) # max(dp[j - 1], dp[j])return res作者:jyd
链接:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/mian-shi-ti-48-zui-chang-bu-han-zhong-fu-zi-fu-d-9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

双指针(简单)

2022/3/6

剑指 Offer 18. 删除链表的节点

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:def deleteNode(self, head: ListNode, val: int) -> ListNode:pre_head = ListNode(-1)pre_head.next = headpre = pre_headp=pre.nextwhile p:if p.val == val:pre.next = p.nextpre = pp = p.nextreturn pre_head.nextelse:pre = pp = p.nextreturn pre_head.next

剑指 Offer 22. 链表中倒数第k个节点

#考虑越界情况
class Solution:def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:former, latter = head, headfor _ in range(k):if not former: returnformer = former.nextwhile former:former, latter = former.next, latter.nextreturn latter作者:jyd
链接:https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/solution/mian-shi-ti-22-lian-biao-zhong-dao-shu-di-kge-j-11/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

双指针(简单)

2022/03/07

剑指 Offer 25. 合并两个排序的链表

class Solution:def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:cur = dum = ListNode(0)while l1 and l2:if l1.val < l2.val:cur.next, l1 = l1, l1.nextelse:cur.next, l2 = l2, l2.nextcur = cur.nextcur.next = l1 if l1 else l2return dum.next作者:jyd
链接:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/solution/mian-shi-ti-25-he-bing-liang-ge-pai-xu-de-lian-b-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:head = ListNode(-1)p=headwhile l1 and l2:if l1.val <= l2.val:node =ListNode(l1.val)p.next = nodep = p.nextl1 = l1.nextelif l1.val>l2.val:node = ListNode(l2.val)p.next = nodep = p.nextl2 = l2.nextif l1:p.next = l1elif l2:p.next = l2return head.next

剑指 Offer 52. 两个链表的第一个公共节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tz0P3cIO-1648863192591)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220307144024241.png)]

class Solution:def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:A, B = headA, headBwhile A != B:A = A.next if A else headBB = B.next if B else headAreturn A作者:jyd
链接:https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/solution/jian-zhi-offer-52-liang-ge-lian-biao-de-gcruu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#快慢指针
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:if not headA or not headB:return Nonel1, l2 = 0, 0p1, p2 = headA, headBwhile p1:l1+=1p1 = p1.nextwhile p2:l2+=1p2 = p2.nextp1, p2 = headA, headBif l1>=l2:tmp = l1-l2while tmp and p1:tmp-=1p1 = p1.nextelse:tmp = l2-l1while tmp and p2:tmp-=1p2 = p2.nextwhile p1 and p2:if p1==p2:return p1else:p1 = p1.nextp2 = p2.nextreturn None

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

#快排
class Solution:def exchange(self, nums: List[int]) -> List[int]:i, j = 0, len(nums) - 1while i < j:while i < j and nums[i] & 1 == 1: i += 1while i < j and nums[j] & 1 == 0: j -= 1nums[i], nums[j] = nums[j], nums[i]return nums作者:jyd
链接:https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/solution/mian-shi-ti-21-diao-zheng-shu-zu-shun-xu-shi-qi-4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:def exchange(self, nums: List[int]) -> List[int]:l = len(nums)left, right = 0, l-1while left<right:while left<right and nums[left]%2==1:left+=1while right>left and nums[right]%2==0:right-=1tmp = nums[left]nums[left] = nums[right]nums[right] = tmpleft += 1right -= 1return nums

剑指 Offer 57. 和为s的两个数字

class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:i, j = 0, len(nums) - 1while i < j:s = nums[i] + nums[j]if s > target: j -= 1elif s < target: i += 1else: return nums[i], nums[j]return []作者:jyd
链接:https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof/solution/mian-shi-ti-57-he-wei-s-de-liang-ge-shu-zi-shuang-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:i, j = 0, len(nums)-1while i<=len(nums)-1 and j>=0:if nums[i]+nums[j]==target: return [nums[i], nums[j]]elif nums[i]+nums[j]>target: j-=1else: i+=1return []

剑指 Offer 58 - I. 翻转单词顺序

#切片反转
class Solution:def reverseWords(self, s: str) -> str:ch = s.split(" ")res = ""for c in ch[::-1]:if c != "":res = res+c+" "else: continuereturn res[:-1]
#切割翻转
class Solution:def reverseWords(self, s: str) -> str:s = s.strip() # 删除首尾空格strs = s.split() # 分割字符串strs.reverse() # 翻转单词列表return ' '.join(strs) # 拼接为字符串并返回
class Solution:def reverseWords(self, s: str) -> str:return ' '.join(s.strip().split()[::-1])作者:jyd
链接:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/mian-shi-ti-58-i-fan-zhuan-dan-ci-shun-xu-shuang-z/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#倒序遍历
class Solution:def reverseWords(self, s: str) -> str:s = s.strip() # 删除首尾空格i = j = len(s) - 1res = []while i >= 0:while i >= 0 and s[i] != ' ': i -= 1 # 搜索首个空格res.append(s[i + 1: j + 1]) # 添加单词while s[i] == ' ': i -= 1 # 跳过单词间空格j = i # j 指向下个单词的尾字符return ' '.join(res) # 拼接并返回作者:jyd
链接:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/mian-shi-ti-58-i-fan-zhuan-dan-ci-shun-xu-shuang-z/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

搜索与回溯算法(中等)

剑指 Offer 12. 矩阵中的路径

典型的矩阵搜索问题,可使用深度优先搜索(DFS)+剪枝解决:

深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。
剪枝: 在搜索中,遇到 这条路不可能和目标字符串匹配成功 的情况(例如:此矩阵元素和目标字符不同、此元素已被访问),则应立即返回,称之为 可行性剪枝 。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J8AgkRe8-1648863192592)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220308142432780.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SvjhvXsL-1648863192592)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220308142513261.png)]

class Solution:def exist(self, board: List[List[str]], word: str) -> bool:def dfs(i, j, k):if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]: return Falseif k == len(word) - 1: return Trueboard[i][j] = ''res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)board[i][j] = word[k]return resfor i in range(len(board)):for j in range(len(board[0])):if dfs(i, j, 0): return Truereturn False作者:jyd
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/mian-shi-ti-12-ju-zhen-zhong-de-lu-jing-shen-du-yo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 13. 机器人的运动范围

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YHseBfgl-1648863192593)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220308151655309.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XO0WiTPH-1648863192594)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220308152105533.png)]

class Solution:def movingCount(self, m: int, n: int, k: int) -> int:def dfs(i, j, si, sj):if i >= m or j >= n or k < si + sj or (i, j) in visited: return 0visited.add((i,j))return 1 + dfs(i + 1, j, si + 1 if (i + 1) % 10 else si - 8, sj) + dfs(i, j + 1, si, sj + 1 if (j + 1) % 10 else sj - 8)visited = set()return dfs(0, 0, 0, 0)作者:jyd
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/mian-shi-ti-13-ji-qi-ren-de-yun-dong-fan-wei-dfs-b/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:def movingCount(self, m: int, n: int, k: int) -> int:visit = [[0]*n for row in range(m)] count = 0def sums(x):s = 0while x!=0:s += x%10x = x//10return sdef dfs(i, j):if sums(i)+sums(j) > k or not 0<=i<m or not 0<=j<n or visit[i][j]:print(sums(i)+sums(j))return 0print(i,j)visit[i][j] = 1return 1+dfs(i+1, j) + dfs(i, j+1)return dfs(0,0)

剑指 Offer 34. 二叉树中和为某一值的路径

解题思路:

本问题是典型的二叉树方案搜索问题,使用回溯法解决,其包含 先序遍历 + 路径记录 两部分。

先序遍历: 按照 “根、左、右” 的顺序,遍历树的所有节点。
路径记录: 在先序遍历中,记录从根节点到当前节点的路径。当路径为 ① 根节点到叶节点形成的路径 且 ② 各节点值的和等于目标值 sum 时,将此路径加入结果列表。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aEqIXmIV-1648863192594)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309130931543.png)]

class Solution:def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:res, path = [], []def recur(root, tar):if not root: returnpath.append(root.val)tar -= root.valif tar == 0 and not root.left and not root.right:res.append(list(path))recur(root.left, tar)recur(root.right, tar)path.pop()recur(root, sum)return res作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/solution/mian-shi-ti-34-er-cha-shu-zhong-he-wei-mou-yi-zh-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0tlTXd8Q-1648863192595)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309133325242.png)]

剑指 Offer 36. 二叉搜索树与双向链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AB97BdcP-1648863192596)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309151353146.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aoYvgqr8-1648863192596)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309153342851.png)]

class Solution:def treeToDoublyList(self, root: 'Node') -> 'Node':def dfs(cur):if not cur: returndfs(cur.left) # 递归左子树if self.pre: # 修改节点引用self.pre.right, cur.left = cur, self.preelse: # 记录头节点self.head = curself.pre = cur # 保存 curdfs(cur.right) # 递归右子树if not root: returnself.pre = Nonedfs(root)self.head.left, self.pre.right = self.pre, self.headreturn self.head作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/solution/mian-shi-ti-36-er-cha-sou-suo-shu-yu-shuang-xian-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 54. 二叉搜索树的第k大节点

本文解法基于此性质:二叉搜索树的中序遍历为 递增序列 。

根据以上性质,易得二叉搜索树的 中序遍历倒序 为 递减序列 。
因此,求 “二叉搜索树第 kkk 大的节点” 可转化为求 “此树的中序遍历倒序的第 kkk 个节点”。

中序遍历 为 “左、根、右” 顺序

中序遍历的倒序 为 “右、根、左” 顺序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f3wfIJRJ-1648863192597)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309164751245.png)]

class Solution:def kthLargest(self, root: TreeNode, k: int) -> int:def dfs(root):if not root: returndfs(root.right)if self.k == 0: returnself.k -= 1if self.k == 0: self.res = root.valdfs(root.left)self.k = kdfs(root)return self.res作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/solution/mian-shi-ti-54-er-cha-sou-suo-shu-de-di-k-da-jie-d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:def kthLargest(self, root: TreeNode, k: int) -> int:que = []def dfs(cur):if not cur: returndfs(cur.left)que.append(cur.val)dfs(cur.right)if not root: return Nonedfs(root)print(que)return que[-k]

2022/3/10

python数据类型

不可变数据类型: 当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,就称不可变数据类型。

**可变数据类型 :**当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型。

数据类型 可变/不可变
整型 不可变
字符串 不可变
元组 不可变(只可读)
列表 可变
集合 可变
字典 可变

排序(简单)

剑指 Offer 45. 把数组排成最小的数

此题求拼接起来的最小数字,本质上是一个排序问题。设数组 nums中任意两数字的字符串为 x 和 y ,则规定 排序判断规则 为:

若拼接字符串 x+y>y+x ,则 x “大于” y ;
反之,若 x+y<y+x,则 x “小于” y ;

class Solution:def minNumber(self, nums: List[int]) -> str:def quick_sort(l , r):if l >= r: returni, j = l, rwhile i < j:while strs[j] + strs[l] >= strs[l] + strs[j] and i < j: j -= 1while strs[i] + strs[l] <= strs[l] + strs[i] and i < j: i += 1strs[i], strs[j] = strs[j], strs[i]strs[i], strs[l] = strs[l], strs[i]quick_sort(l, i - 1)quick_sort(i + 1, r)strs = [str(num) for num in nums]quick_sort(0, len(strs) - 1)return ''.join(strs)作者:jyd
链接:https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/solution/mian-shi-ti-45-ba-shu-zu-pai-cheng-zui-xiao-de-s-4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:def minNumber(self, nums: List[int]) -> str:for i in range(len(nums)):for j in range(0, len(nums)):if str(nums[i])+str(nums[j])<str(nums[j])+str(nums[i]):nums[i],nums[j] = nums[j], nums[i]print(nums)res = "".join(str(n) for n in nums)return res

剑指 Offer 61. 扑克牌中的顺子

class Solution:def isStraight(self, nums: List[int]) -> bool:repeat = set()ma, mi = 0, 14for num in nums:if num == 0: continue # 跳过大小王ma = max(ma, num) # 最大牌mi = min(mi, num) # 最小牌if num in repeat: return False # 若有重复,提前返回 falserepeat.add(num) # 添加牌至 Setreturn ma - mi < 5 # 最大牌 - 最小牌 < 5 则可构成顺子 作者:jyd
链接:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/solution/mian-shi-ti-61-bu-ke-pai-zhong-de-shun-zi-ji-he-se/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。class Solution:def isStraight(self, nums: List[int]) -> bool:joker = 0nums.sort() # 数组排序for i in range(4):if nums[i] == 0: joker += 1 # 统计大小王数量elif nums[i] == nums[i + 1]: return False # 若有重复,提前返回 falsereturn nums[4] - nums[joker] < 5 # 最大牌 - 最小牌 < 5 则可构成顺子作者:jyd
链接:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/solution/mian-shi-ti-61-bu-ke-pai-zhong-de-shun-zi-ji-he-se/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

排序(中等)

剑指 Offer 40. 最小的k个数

#快排
class Solution:def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:def quick_sort(arr, l, r):if l>=r: returni, j = l, rwhile i<j: while i<j and arr[j]>=arr[l]: j-=1while i<j and arr[i]<=arr[l]: i+=1  arr[i], arr[j] = arr[j], arr[i]                   arr[l], arr[i] = arr[i], arr[l]quick_sort(arr, l, i-1)quick_sort(arr,i+1, r)quick_sort(arr, 0, len(arr)-1)return arr[:k]

剑指 Offer 41. 数据流中的中位数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qfUIRGKj-1648863192597)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220311153752546.png)]

from heapq import *class MedianFinder:def __init__(self):self.A = [] # 小顶堆,保存较大的一半self.B = [] # 大顶堆,保存较小的一半def addNum(self, num: int) -> None:if len(self.A) != len(self.B):heappush(self.B, -heappushpop(self.A, num))else:heappush(self.A, -heappushpop(self.B, -num))def findMedian(self) -> float:return self.A[0] if len(self.A) != len(self.B) else (self.A[0] - self.B[0]) / 2.0作者:jyd
链接:https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/solution/mian-shi-ti-41-shu-ju-liu-zhong-de-zhong-wei-shu-y/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#by Mallika
class MedianFinder:def __init__(self):"""initialize your data structure here."""self.nums = []self.length = 0def addNum(self, num: int) -> None:if not self.length:self.nums.append(num)self.length+=1else:pos=0while pos<self.length and self.nums[pos]<=num:pos+=1self.nums.insert(pos, num)self.length+=1returndef findMedian(self) -> float:if self.length==0: return self.numselif self.length==1: return self.nums[0]elif self.length % 2:return self.nums[int(self.length/2)]else:return (self.nums[int((self.length-1)/2)]+self.nums[int((self.length-1)/2)+1])/

搜索与回溯算法(中等)

*剑指 Offer 55 - I. 二叉树的深度

class Solution:def maxDepth(self, root: TreeNode) -> int:if not root: return 0return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/mian-shi-ti-55-i-er-cha-shu-de-shen-du-xian-xu-bia/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#层次遍历
class Solution:def maxDepth(self, root: TreeNode) -> int:if not root: return 0queue, res = [root], 0while queue:tmp = []for node in queue:if node.left: tmp.append(node.left)if node.right: tmp.append(node.right)queue = tmpres += 1return res作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/mian-shi-ti-55-i-er-cha-shu-de-shen-du-xian-xu-bia/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#by Mallika
class Solution:def maxDepth(self, root: TreeNode) -> int:if not root: return 0que = collections.deque()que.append(root)res = 0tmp = []while que:node = que.popleft()# print(node.val)if node.left: tmp.append(node.left)if node.right: tmp.append(node.right)if not len(que):res+=1for t in tmp:que.append(t)tmp = []

* 剑指 Offer 55 - II. 平衡二叉树

以下两种方法均基于以下性质推出: 此树的深度 等于 左子树的深度右子树的深度 中的 最大值 +1 。

方法一: 后序遍历+剪枝(从底至顶)

思路是对二叉树做后序遍历,从底至顶返回子树深度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6UHhIcV1-1648863192598)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312145701120.png)]

#后序遍历+剪枝
class Solution:def isBalanced(self, root: TreeNode) -> bool:def recur(root):if not root: return 0left = recur(root.left)if left == -1: return -1right = recur(root.right)if right == -1: return -1return max(left, right) + 1 if abs(left - right) <= 1 else -1return recur(root) != -1作者:jyd
链接:https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/solution/mian-shi-ti-55-ii-ping-heng-er-cha-shu-cong-di-zhi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#先序遍历+判断深度
class Solution:def isBalanced(self, root: TreeNode) -> bool:if not root: return Truereturn abs(self.depth(root.left) - self.depth(root.right)) <= 1 and \self.isBalanced(root.left) and self.isBalanced(root.right)def depth(self, root):if not root: return 0return max(self.depth(root.left), self.depth(root.right)) + 1作者:jyd
链接:https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/solution/mian-shi-ti-55-ii-ping-heng-er-cha-shu-cong-di-zhi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。#Mallika
class Solution:def isBalanced(self, root: TreeNode) -> bool:def maxDepth(root):if not root: return 0 return max(maxDepth(root.left), maxDepth(root.right))+1def maxDiff(root):if not root: return Trueque = []que.append(root)while que:node = que.pop()if maxDepth(node.left)-maxDepth(node.right)!=0 and maxDepth(node.left)-maxDepth(node.right)!=1 and maxDepth(node.left)-maxDepth(node.right)!=-1:return Falseif node.left: que.append(node.left)if node.right: que.append(node.right)return True

搜索与回溯算法

*剑指 Offer 64. 求1+2+…+n

逻辑运算解答

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aFqn2nww-1648863192599)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313105447722.png)]

class Solution:def __init__(self):self.res = 0def sumNums(self, n: int) -> int:n>1 and self.sumNums(n-1)self.res+=nreturn self.res

复杂度分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wDGh8o5U-1648863192599)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313110154167.png)]

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

最近公共祖先的定义: 设节点 root 为节点 p,q 的某公共祖先,若其左子节点 root.left 和右子节点 root.right 都不是 p,q 的公共祖先,则称 root 是 “最近的公共祖先” 。

根据以上定义,若 root 是 p,q 的 最近公共祖先 ,则只可能为以下情况之一:

p 和 q 在 root 的子树中,且分列 roott的 异侧(即分别在左、右子树中);
p=root,且 q 在 roott 的左或右子树中;
q=root,且 p 在 root 的左或右子树中;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kpnzn2RT-1648863192600)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313113039265.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BaRHYIUo-1648863192600)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313113105821.png)]

#迭代
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = Noneclass Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if p.val>q.val: p, q = q, pwhile root:if not root: return rootelif root.val < p.val: root = root.rightelif root.val > q.val: root = root.leftelse: breakreturn root

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2p5E2j1-1648863192601)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313114105613.png)]

#递归
class Solution:def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':if root.val < p.val and root.val < q.val:return self.lowestCommonAncestor(root.right, p, q)if root.val > p.val and root.val > q.val:return self.lowestCommonAncestor(root.left, p, q)return root作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/mian-shi-ti-68-i-er-cha-sou-suo-shu-de-zui-jin-g-7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分治法

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWpis3co-1648863192602)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313152746920.png)]

class Solution:def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:if not root or root == p or root == q: return rootleft = self.lowestCommonAncestor(root.left, p, q)right = self.lowestCommonAncestor(root.right, p, q)if not left and not right: return # 1.if not left: return right # 3.if not right: return left # 4.return root # 2. if left and right:作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/mian-shi-ti-68-ii-er-cha-shu-de-zui-jin-gong-gon-7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mEobju4N-1648863192603)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313152757198.png)]

剑指 Offer 16. 数值的整数次方

快速幂法:

"二分法", "二进制"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koXKmw7F-1648863192603)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314111711167.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jhCeEOXO-1648863192604)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314112048891.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yoh9zN58-1648863192604)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314112102195.png)]

时间复杂度空间复杂度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F7Oa2TDI-1648863192605)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314112120087.png)]

class Solution:def myPow(self, x: float, n: int) -> float:if x == 0: return 0res = 1if n < 0: x, n = 1 / x, -nwhile n:if n & 1: res *= xx *= xn >>= 1return res作者:jyd
链接:https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/solution/mian-shi-ti-16-shu-zhi-de-zheng-shu-ci-fang-kuai-s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 33. 二叉搜索树的后序遍历序列


位运算(简单)

剑指 Offer 15. 二进制中1的个数

def hammingWeighted(self, n:int)->int:res=0while n:#res += n&1n>>=1res+=1n&=(n-1)return res

剑指 Offer 65. 不用加减乘除做加法

a(i) b(i) 无进位和n(i) 进位和(i+1)
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

无进位和异或运算 规律相同,进位与运算 规律相同(并需左移一位)。

非进位和:异或运算进位:n=a⊕b

与运算+左移一位: c=a&b<<1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VNekGoSa-1648863192605)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220317222312585.png)]

class Solution:def add(self, a: int, b: int) -> int:x = 0xffffffffa, b = a & x, b & xwhile b != 0:a, b = (a ^ b), (a & b) << 1 & xreturn a if a <= 0x7fffffff else ~(a ^ x)作者:jyd
链接:https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

位运算(中等)

剑指 Offer 56 - I. 数组中数字出现的次数

class Solution:def singleNumbers(self, nums: List[int]) -> List[int]:x, y, n, m = 0, 0, 0, 1for num in nums:         # 1. 遍历异或n ^= numwhile n & m == 0:        # 2. 循环左移,计算 mm <<= 1       for num in nums:         # 3. 遍历 nums 分组if num & m: x ^= num # 4. 当 num & m != 0else: y ^= num       # 4. 当 num & m == 0return x, y              # 5. 返回出现一次的数字作者:jyd
链接:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/jian-zhi-offer-56-i-shu-zu-zhong-shu-zi-tykom/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

数学(简单)

数学(中等)

剑指 Offer 14- I. 剪绳子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5KDktg2-1648863192606)(Leetcode刷题.assets/image-20220321213720186.png)]

class Solution:def cuttingRope(self, n: int) -> int:dp = [0] * (n + 1)dp[2] = 1for i in range(3, n + 1):for j in range(2, i):dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))return dp[n]作者:edelweisskoko
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/jian-zhi-offer-14-i-jian-sheng-zi-huan-s-xopj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 57 - II. 和为s的连续正数序列

双指针/数学求和公式

class Solution:def findContinuousSequence(self, target: int) -> List[List[int]]:i, j, s, res = 1, 2, 3, []while i < j:if s == target:res.append(list(range(i, j + 1)))if s >= target:s -= ii += 1else:j += 1s += jreturn res作者:jyd
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/jian-zhi-offer-57-ii-he-wei-s-de-lian-xu-t85z/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 62. 圆圈中最后剩下的数字

class Solution:def lastRemaining(self, n: int, m: int) -> int:x = 0for i in range(2, n + 1):x = (x + m) % ireturn x作者:jyd
链接:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/jian-zhi-offer-62-yuan-quan-zhong-zui-ho-dcow/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

数据结构(中)

数组

136. 只出现一次的数字

hash表,set集合,异或。

#hash
class Solution:def singleNumber(self, nums: List[int]) -> int:dic = {}for n in nums:dic[n] = 1 if not dic.get(n) else 0for k in dic.keys():if dic[k]:res = kreturn res#set
class Solution:def singleNumber(self, nums: List[int]) -> int:s = set()for n in nums:if n not in s:s.add(n)else: s.remove(n)return s.pop()#异或
class Solution:def singleNumber(self, nums: List[int]) -> int:res = 0for num in nums:res ^= numreturn res作者:tao-zhi-r
链接:https://leetcode-cn.com/problems/single-number/solution/ban-yuan-xiu-dao-duo-chong-yu-yan-yi-huo-zzoa/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

169. 多数元素

hash, 摩尔投票法-多数投票法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jDbVSgUY-1648863192606)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312165428719.png)]

class Solution:def majorityElement(self, nums: List[int]) -> int:count = 0candidate = Nonefor num in nums:if count == 0:candidate = numcount += (1 if num == candidate else -1)return candidate作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/majority-element/solution/duo-shu-yuan-su-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#hash
class Solution:def majorityElement(self, nums: List[int]) -> int:counts = collections.Counter(nums)return max(counts.keys(), key=counts.get)作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/majority-element/solution/duo-shu-yuan-su-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

15. 三数之和

排序+双指针

复杂度:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xThokwlz-1648863192606)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312201539941.png)]

class Solution:def threeSum(self, nums: [int]) -> [[int]]:nums.sort()res, k = [], 0for k in range(len(nums) - 2):if nums[k] > 0: break # 1. because of j > i > k.if k > 0 and nums[k] == nums[k - 1]: continue # 2. skip the same `nums[k]`.i, j = k + 1, len(nums) - 1while i < j: # 3. double pointers = nums[k] + nums[i] + nums[j]if s < 0:i += 1while i < j and nums[i] == nums[i - 1]: i += 1elif s > 0:j -= 1while i < j and nums[j] == nums[j + 1]: j -= 1else:res.append([nums[k], nums[i], nums[j]])i += 1j -= 1while i < j and nums[i] == nums[i - 1]: i += 1while i < j and nums[j] == nums[j + 1]: j -= 1return res作者:jyd
链接:https://leetcode-cn.com/problems/3sum/solution/3sumpai-xu-shuang-zhi-zhen-yi-dong-by-jyd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分治算法(中等)

剑指 Offer 07. 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

分治法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pGe5loR2-1648863192607)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314100621322.png)]

按照先序顺序构造节点,按照中序划分子树
class Solution:def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:def recur(root, left, right):if left > right: return                               # 递归终止node = TreeNode(preorder[root])                       # 建立根节点i = dic[preorder[root]]                               # 划分根节点、左子树、右子树node.left = recur(root + 1, left, i - 1)              # 开启左子树递归node.right = recur(i - left + root + 1, i + 1, right) # 开启右子树递归return node                                           # 回溯返回根节点dic, preorder = {}, preorderfor i in range(len(inorder)):dic[inorder[i]] = ireturn recur(0, 0, len(inorder) - 1)作者:jyd
链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-di-gui-fa-qin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

美团

93. 复原 IP 地址

class Solution:def restoreIpAddresses(self, s: str) -> List[str]:SEG_COUNT = 4ans = list()segments = [0] * SEG_COUNTdef dfs(segId: int, segStart: int):# 如果找到了 4 段 IP 地址并且遍历完了字符串,那么就是一种答案if segId == SEG_COUNT:if segStart == len(s):ipAddr = ".".join(str(seg) for seg in segments)ans.append(ipAddr)return# 如果还没有找到 4 段 IP 地址就已经遍历完了字符串,那么提前回溯if segStart == len(s):return# 由于不能有前导零,如果当前数字为 0,那么这一段 IP 地址只能为 0if s[segStart] == "0":segments[segId] = 0dfs(segId + 1, segStart + 1)# 一般情况,枚举每一种可能性并递归addr = 0for segEnd in range(segStart, len(s)):addr = addr * 10 + (ord(s[segEnd]) - ord("0"))if 0 < addr <= 0xFF:segments[segId] = addrdfs(segId + 1, segEnd + 1)else:breakdfs(0, 0)return ans作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/restore-ip-addresses/solution/fu-yuan-ipdi-zhi-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

46. 全排列

class Solution:def permute(self, nums):""":type nums: List[int]:rtype: List[List[int]]"""def backtrack(first = 0):# 所有数都填完了if first == n:  res.append(nums[:])for i in range(first, n):# 动态维护数组nums[first], nums[i] = nums[i], nums[first]# 继续递归填下一个数backtrack(first + 1)# 撤销操作nums[first], nums[i] = nums[i], nums[first]n = len(nums)res = []backtrack()return res作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/permutations/solution/quan-pai-lie-by-leetcode-solution-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

53. 最大子数组和

class Solution:def maxSubArray(self, nums: List[int]) -> int:for i in range(len(nums)):if i==0: continuenums[i] = max(nums[i], nums[i-1]+nums[i])print(nums)return max(nums)

8. 字符串转换整数 (atoi)

import re
class Solution:def myAtoi(self, str: str) -> int:INT_MAX = 2147483647    INT_MIN = -2147483648str = str.lstrip()      #清除左边多余的空格num_re = re.compile(r'^[\+\-]?\d+')   #设置正则规则num = num_re.findall(str)   #查找匹配的内容num = int(*num) #由于返回的是个列表,解包并且转换成整数return max(min(num,INT_MAX),INT_MIN)    #返回值
class Solution:def myAtoi(self, s: str) -> int:s = s.strip()p = Falseif len(s)!=0:s = list(s)else: return 0if s[0] == "-" or s[0] == "+":count = 1for i in range(1,len(s)):if (s[i]<"0" or s[i]>"9"):breakcount+=1if count!=1: res = ''.join(s[:count])else:return 0elif s[0]>="0" and s[0]<="9":count = 0for i in range(len(s)):if (s[i]<"0" or s[i]>"9"):breakcount+=1res = ''.join(s[:count])else:return 0if s[0]=="-":res = max(int(res),pow(-2,31))return reselif s[0]=="+":return min(int(res), pow(2, 31)-1)else:return min(int(res), pow(2, 31)-1)

, len(s)):
addr = addr * 10 + (ord(s[segEnd]) - ord(“0”))
if 0 < addr <= 0xFF:
segments[segId] = addr
dfs(segId + 1, segEnd + 1)
else:
break

    dfs(0, 0)return ans

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/restore-ip-addresses/solution/fu-yuan-ipdi-zhi-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


#### [46. 全排列](https://leetcode-cn.com/problems/permutations/)```python
class Solution:def permute(self, nums):""":type nums: List[int]:rtype: List[List[int]]"""def backtrack(first = 0):# 所有数都填完了if first == n:  res.append(nums[:])for i in range(first, n):# 动态维护数组nums[first], nums[i] = nums[i], nums[first]# 继续递归填下一个数backtrack(first + 1)# 撤销操作nums[first], nums[i] = nums[i], nums[first]n = len(nums)res = []backtrack()return res作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/permutations/solution/quan-pai-lie-by-leetcode-solution-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

53. 最大子数组和

class Solution:def maxSubArray(self, nums: List[int]) -> int:for i in range(len(nums)):if i==0: continuenums[i] = max(nums[i], nums[i-1]+nums[i])print(nums)return max(nums)

8. 字符串转换整数 (atoi)

import re
class Solution:def myAtoi(self, str: str) -> int:INT_MAX = 2147483647    INT_MIN = -2147483648str = str.lstrip()      #清除左边多余的空格num_re = re.compile(r'^[\+\-]?\d+')   #设置正则规则num = num_re.findall(str)   #查找匹配的内容num = int(*num) #由于返回的是个列表,解包并且转换成整数return max(min(num,INT_MAX),INT_MIN)    #返回值
class Solution:def myAtoi(self, s: str) -> int:s = s.strip()p = Falseif len(s)!=0:s = list(s)else: return 0if s[0] == "-" or s[0] == "+":count = 1for i in range(1,len(s)):if (s[i]<"0" or s[i]>"9"):breakcount+=1if count!=1: res = ''.join(s[:count])else:return 0elif s[0]>="0" and s[0]<="9":count = 0for i in range(len(s)):if (s[i]<"0" or s[i]>"9"):breakcount+=1res = ''.join(s[:count])else:return 0if s[0]=="-":res = max(int(res),pow(-2,31))return reselif s[0]=="+":return min(int(res), pow(2, 31)-1)else:return min(int(res), pow(2, 31)-1)

Leetcode刷题相关推荐

  1. LeetCode刷题记录15——21. Merge Two Sorted Lists(easy)

    LeetCode刷题记录15--21. Merge Two Sorted Lists(easy) 目录 LeetCode刷题记录15--21. Merge Two Sorted Lists(easy) ...

  2. LeetCode刷题记录14——257. Binary Tree Paths(easy)

    LeetCode刷题记录14--257. Binary Tree Paths(easy) 目录 前言 题目 语言 思路 源码 后记 前言 数据结构感觉理论简单,实践起来很困难. 题目 给定一个二叉树, ...

  3. LeetCode刷题记录13——705. Design HashSet(easy)

    LeetCode刷题记录13--705. Design HashSet(easy) 目录 LeetCode刷题记录13--705. Design HashSet(easy) 前言 题目 语言 思路 源 ...

  4. LeetCode刷题记录12——232. Implement Queue using Stacks(easy)

    LeetCode刷题记录12--232. Implement Queue using Stacks(easy) 目录 LeetCode刷题记录12--232. Implement Queue usin ...

  5. LeetCode刷题记录11——290. Word Pattern(easy)

    LeetCode刷题记录11--290. Word Pattern(easy) 目录 LeetCode刷题记录11--290. Word Pattern(easy) 题目 语言 思路 源码 后记 题目 ...

  6. LeetCode刷题记录10——434. Number of Segments in a String(easy)

    LeetCode刷题记录10--434. Number of Segments in a String(easy) 目录 LeetCode刷题记录9--434. Number of Segments ...

  7. LeetCode刷题记录9——58. Length of Last Word(easy)

    LeetCode刷题记录9--58. Length of Last Word(easy) 目录 LeetCode刷题记录9--58. Length of Last Word(easy) 题目 语言 思 ...

  8. LeetCode刷题记录8——605. Can Place Flowers(easy)

    LeetCode刷题记录8--605. Can Place Flowers(easy) 目录 LeetCode刷题记录8--605. Can Place Flowers(easy) 题目 语言 思路 ...

  9. LeetCode刷题记录7——824. Goat Latin(easy)

    LeetCode刷题记录7--824. Goat Latin(easy) 目录 LeetCode刷题记录7--824. Goat Latin(easy) 题目 语言 思路 后记 题目 题目需要将一个输 ...

  10. LeetCode刷题记录6——696. Count Binary Substrings(easy)

    LeetCode刷题记录6--696. Count Binary Substrings(easy) 目录 LeetCode刷题记录6--696. Count Binary Substrings(eas ...

最新文章

  1. 等差数列连续异或模板
  2. 排序--直接插入排序
  3. Ubuntu 命令行打开pdf文件和打开命令行当前目录
  4. boost::hana::chain用法的测试程序
  5. Redis工具类封装讲解和实战
  6. jzoj1252,P5194-天平【dfs,set】
  7. tomcat在linux下开机启动
  8. php三维数组转换二维数组,php 三维数组转二维数组(多维数组变合拼二维数组)(foreach循环 数组叠加)...
  9. linux登录界面说明,Linux登录界面以及简单使用入门
  10. java常用英语单词大全
  11. The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
  12. vue实现点击不同按钮展示不同内容
  13. 惠普HP LaserJet Pro M305d 打印机驱动
  14. html调用 另存为,:将html另存为文本
  15. 写的一个网页登录注册模板(css+js),注册成功后把账号保存到MySQL数据库,登录时从数据库查找进行验证(jsp+javabean)
  16. 程序员被人喜欢的13点原因
  17. dede修改描述description限制字数长度
  18. 用Python写了一个上课点名系统(附源码)
  19. 酷我音乐linux版本,酷我音乐盒的 Gtk/Linux 实现 – v2.5 版本发布
  20. LeetCode之路:122. Best Time to Buy and Sell Stock II

热门文章

  1. 数据结构与算法|第1节
  2. 逗游怎么安装计算机丢失文件,逗游怎么安装 逗游游戏宝库安装教程
  3. 查看电脑的IP和端口
  4. python绘制余弦曲线图_Python绘制正余弦函数图像
  5. 详情小三角css,CSS实现小三角
  6. 远程控制基恩士plc
  7. PVE导入img为磁盘
  8. 各种选址、点、路线、网要求
  9. 微信小程序nfc读取数据
  10. 如何解决浏览器弹出窗口的拦截