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] = i
return []
#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 True
if x!=0 and x%10 == 0: #前面已经判断了,可以不判断0
return False
if x<0:
return False
rx=0
while(rx<x):
rx = 10*rx + x%10
x = x//10
print("rx, x", rx,x)
if rx ==x:
return True
if rx>x and rx//10==x:
return True
else:
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-1
low = 0
while low<=high :
mid = (low+high)/2
if nums[mid]==target:
return mid
elif nums[mid]>target:
high = mid-1
elif nums[mid]<target:
low = mid+1
return -1
278.第一个错误的版本
class Solution:
def firstBadVersion(self, n):
"""
:type n: int
:rtype: int
"""
l, r = 1, n
while l <= r: # 重点一:l <= r
mid = (l+r)//2
if isBadVersion(mid):
r = mid - 1
else:
l = mid + 1
return 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 = i
ans = list()
p,q = neg,neg+1
while p>=0 or q<length:
if p<0:
ans.append(nums[q]*nums[ q])
q+=1
elif q==length:
ans.append(nums[p]*nums[p])
p-=1
elif nums[p]*nums[p] <= nums[q]*nums[q]:
ans.append(nums[p]*nums[p])
p-=1
elif nums[p]*nums[p] > nums[q]*nums[q]:
ans.append(nums[q]*nums[q])
q+=1
return 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 %= n
nums.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, 0
length = len(nums)
while nonzero<length:
if nums[nonzero]!=0:
nums[h]=nums[nonzero]
h+=1
nonzero+=1
for i in range(h, length):
nums[i]=0
#双指针
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
n = len(nums)
left = right = 0
while right < n:
if nums[right] != 0:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right += 1
print(nums)
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
length = len(numbers)
left,right = 0, length-1
while left < right:
total = numbers[left]+numbers[right]
if total == target:
return [left+1, right+1]
elif total < target:
left+=1
elif total > target:
right-=1
return [-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-1
while left < right:
tmp = s[left]
s[left] = s[right]
s[right] = tmp
left+=1
right-=1
#双指针
class Solution:
def reverseWords(self, s: str) -> str:
ans = ''
words = s.split(' ')
for idx, word in enumerate(words):
rs = ''.join(reversed(word))
ans = ans + rs
print(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
# 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, head
while fast != None:
if fast.next == None:
return slow
if fast.next == None:
return slow.next
slow = slow.next
fast = fast.next.next
return slow
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
def checkInclusion(self, s1: str, s2: str) -> bool:
counter1 = collections.Counter(s1)
n1, n2 = len(s1), len(s2)
left = 0
right = left + n1
while right<=n2 and left <=n2:
counter2 = collections.Counter(s2[left:right])
if counter1 == counter2:
return True
left+=1
right+=1
return 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 = 0
right = len(s1) - 1
# 统计窗口s2[left, right - 1]内的元素出现的次数
counter2 = collections.Counter(s2[0:right])
while right < N:
# 把 right 位置的元素放到 counter2 中
counter2[s2[right]] += 1
# 如果滑动窗口内各个元素出现的次数跟 s1 的元素出现次数完全一致,返回 True
if counter1 == counter2:
return True
# 窗口向右移动前,把当前 left 位置的元素出现次数 - 1
counter2[s2[left]] -= 1
# 如果当前 left 位置的元素出现次数为 0, 需要从字典中删除,否则这个出现次数为 0 的元素会影响两 counter 之间的比较
if counter2[s2[left]] == 0:
del counter2[s2[left]]
# 窗口向右移动
left += 1
right += 1
return 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 (广度优先搜索/宽度优先搜索)
#广度优先
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 image
n, m = len(image), len(image[0])
que = collections.deque([(sr, sc)])
image[sr][sc] = newColor
while 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] = newColor
return 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] = newColor
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:
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#深度优先搜索
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 0
grid[cur_i][cur_j]=0
ans = 1
for di, dj in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
next_i, next_j = cur_i + di, cur_j + dj
ans += self.dfs(grid, next_i, next_j)
return ans
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
ans = 0
for i, l in enumerate(grid):
for j, n in enumerate(l):
ans = max(self.dfs(grid, i, j), ans)
return ans
2022/1/26
# 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 root2
if not root2:
return root1
merged = TreeNode(root1.val+root2.val)
merged.left = self.mergeTrees(root1.left, root2.left)
merged.right = self.mergeTrees(root1.right, root2.right)
return merged
层次遍历基于广度优先搜索,它与广度优先搜索的不同之处在于,广度优先搜索每次只会取出一个节点来拓展,而层次遍历会每次将队列中的所有元素都拿出来拓展,这样能保证每次从队列中拿出来遍历的元素都是属于同一层的,因此我们可以在遍历的过程中修改每个节点的 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
广度优先搜索和宽度优先搜索
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]+1
q.append((ni, nj))
seen.add((ni, nj))
return dist
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
2022/1/28
递归\回溯
#迭代写法
# 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 = prehead
while l1 and l2:
if l1.val <= l2.val:
prev.next = l1
l1 = l1.next
prev = prev.next
else:
prev.next = l2
l2 = l2.next
prev = prev.next
prev.next = l1 if l1 is not None else l2
return prehead.next
#递归写法
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
if l1 is None:
return l2
elif l2 is None:
return l1
elif l1.val < l2.val:
l1.next = self.mergeTwoLists(l1.next, l2)
return l1
else:
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# 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.next
prehead = ListNode(-1)
prev = prehead
for i in range(len(st)):
tmp = ListNode(st.pop())
prev.next = tmp
prev = prev.next
return prehead.next
2022/2/23
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 -1
else:
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()
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
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reversePrint(self, head: ListNode) -> List[int]:
stack = []
while head:
stack.append(head.val)
head = head.next
return 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 = head
while p:
self.A.append(p.val)
p = p.next
while self.A:
self.res.append(self.A.pop())
return self.res
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def reverseList(self, head: ListNode) -> ListNode:
pre, p = None, head#pre设为None,就可以一并处理了
while p:
after = p.next
p.next = pre
pre = p
p = after
return pre
#哈希表法
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head:
return head
dic = {}
cur = head
while cur:
dic[cur] = Node(cur.val)#键是原链表节点,值是新链表节点
cur = cur.next
cur = head
while cur:
dic[cur].next = dic.get(cur.next)#哈希表 get()返回指定键的值
dic[cur].random = dic.get(cur.random)
cur = cur.next
return dic[head]
#拼接+拆分
class Solution:
def copyRandomList(self, head: 'Node') -> 'Node':
if not head: return
cur = head
# 1. 复制各节点,并构建拼接链表
while cur:
tmp = Node(cur.val)
tmp.next = cur.next
cur.next = tmp
cur = tmp.next
# 2. 构建各新节点的 random 指向
cur = head
while cur:
if cur.random:
cur.next.random = cur.random.next
cur = cur.next.next
# 3. 拆分两链表
cur = res = head.next
pre = head
while cur.next:
pre.next = pre.next.next
cur.next = cur.next.next
pre = pre.next
cur = cur.next
pre.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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
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)
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
class Solution:
def findRepeatNumber(self, nums: List[int]) -> int:
dic = {}
for n in nums:
if not dic.get(n):
dic[n] = 1
else:return n
class Solution:
def findRepeatNumber(self, nums: [int]) -> int:
dic = set()
for num in nums:
if num in dic: return num
dic.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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
def search(self, nums: List[int], target: int) -> int:
dic = {}
for n in nums:
if not dic.get(n):
dic[n] = 1
else:
dic[n]+=1
if 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) - 1
while i <= j:
m = (i + j) // 2
if nums[m] <= tar: i = m + 1
else: j = m - 1
return i
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
def missingNumber(self, nums: List[int]) -> int:
i, j = 0, len(nums)
if nums[i]:
return 0
if j-1 == nums[j-1]:
return j
while i<=j:
mid = int((i+j)/2)
if mid == nums[mid] and mid+1 <nums[mid+1]:
return mid+1
elif mid < nums[mid]:
j = mid-1
elif mid == nums[mid]:
i = mid+1
class Solution:
def missingNumber(self, nums: List[int]) -> int:
i, j = 0, len(nums) - 1
while i <= j:
m = (i + j) // 2
if nums[m] == m: i = m + 1
else: j = m - 1
return 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
#从矩阵 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, 0
while i >= 0 and j < len(matrix[0]):
if matrix[i][j] > target: i -= 1
elif matrix[i][j] < target: j += 1
else: return True
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
def minArray(self, numbers: [int]) -> int:
i, j = 0, len(numbers) - 1
while i < j:
m = (i + j) // 2
if numbers[m] > numbers[j]: i = m + 1
elif numbers[m] < numbers[j]: j = m
else: j -= 1
return 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+=1
elif numbers[i] <= numbers[j]:
min = numbers[i]
if j>i:
j-=1
else :return min
return min
class Solution:
def firstUniqChar(self, s: str) -> str:
dic = {}
for c in s:
dic[c] = not c in dic
for c in s:
if dic[c]: return c
return ' '
作者: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 dic
for k, v in dic.items():
if v: return k
return ' '
作者: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] = 1
else:
dic[c] = dic[c]+1
for c in s:
if dic[c]:
return c
return " "
2022/2/28
#队列
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度分析:
时间复杂度 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 = None
class 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
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 = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
res, que = [], collections.deque()
que.append(root)
flag = False
while 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 flag
return res
2020\03\01
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 True
if not A or A.val != B.val: return False
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
方法一:递归法
根据二叉树镜像的定义,考虑递归遍历(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: return
tmp = root.left
root.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: return
root.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: return
stack = [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.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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
对称二叉树定义: 对于树中 任意两个对称节点 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 True
if not L or not R or L.val != R.val: return False
return 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
此类求 多少种可能性 的题目一般都有 递推性质 ,即 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, 1
for _ in range(n):
a, b = b, a + b
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
青蛙跳台阶问题: 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, 1
for _ in range(n):
a, b = b, a + b
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
动态规划解析:
状态定义: 设动态规划列表 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"), 0
for 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
转移方程: 若 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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: continue
if 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
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 = 1
for i in range(2, len(s) + 1):
a, b = (a + b if "10" <= s[i - 2:i] <= "25" else a), a
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 0
a, b = 1, 1
for 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 b
else:
a+=1
b = a if a>b else b
return b
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
dic = {}
res = tmp = 0
for j in range(len(s)):
i = dic.get(s[j], -1) # 获取索引 i
dic[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
# 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 = head
pre = pre_head
p=pre.next
while p:
if p.val == val:
pre.next = p.next
pre = p
p = p.next
return pre_head.next
else:
pre = p
p = p.next
return pre_head.next
#考虑越界情况
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
former, latter = head, head
for _ in range(k):
if not former: return
former = former.next
while former:
former, latter = former.next, latter.next
return 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
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.next
else:
cur.next, l2 = l2, l2.next
cur = cur.next
cur.next = l1 if l1 else l2
return 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 = None
class Solution:
def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
head = ListNode(-1)
p=head
while l1 and l2:
if l1.val <= l2.val:
node =ListNode(l1.val)
p.next = node
p = p.next
l1 = l1.next
elif l1.val>l2.val:
node = ListNode(l2.val)
p.next = node
p = p.next
l2 = l2.next
if l1:
p.next = l1
elif l2:
p.next = l2
return head.next
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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, headB
while A != B:
A = A.next if A else headB
B = B.next if B else headA
return 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 = None
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
if not headA or not headB:
return None
l1, l2 = 0, 0
p1, p2 = headA, headB
while p1:
l1+=1
p1 = p1.next
while p2:
l2+=1
p2 = p2.next
p1, p2 = headA, headB
if l1>=l2:
tmp = l1-l2
while tmp and p1:
tmp-=1
p1 = p1.next
else:
tmp = l2-l1
while tmp and p2:
tmp-=1
p2 = p2.next
while p1 and p2:
if p1==p2:
return p1
else:
p1 = p1.next
p2 = p2.next
return None
#快排
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
i, j = 0, len(nums) - 1
while i < j:
while i < j and nums[i] & 1 == 1: i += 1
while i < j and nums[j] & 1 == 0: j -= 1
nums[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-1
while left<right:
while left<right and nums[left]%2==1:
left+=1
while right>left and nums[right]%2==0:
right-=1
tmp = nums[left]
nums[left] = nums[right]
nums[right] = tmp
left += 1
right -= 1
return nums
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
i, j = 0, len(nums) - 1
while i < j:
s = nums[i] + nums[j]
if s > target: j -= 1
elif s < target: i += 1
else: 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)-1
while 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-=1
else: i+=1
return []
#切片反转
class Solution:
def reverseWords(self, s: str) -> str:
ch = s.split(" ")
res = ""
for c in ch[::-1]:
if c != "":
res = res+c+" "
else: continue
return 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) - 1
res = []
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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
典型的矩阵搜索问题,可使用深度优先搜索(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 False
if k == len(word) - 1: return True
board[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 res
for i in range(len(board)):
for j in range(len(board[0])):
if dfs(i, j, 0): return True
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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 0
visited.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 = 0
def sums(x):
s = 0
while x!=0:
s += x%10
x = x//10
return s
def 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 0
print(i,j)
visit[i][j] = 1
return 1+dfs(i+1, j) + dfs(i, j+1)
return dfs(0,0)
解题思路:
本问题是典型的二叉树方案搜索问题,使用回溯法解决,其包含 先序遍历 + 路径记录 两部分。
先序遍历: 按照 “根、左、右” 的顺序,遍历树的所有节点。
路径记录: 在先序遍历中,记录从根节点到当前节点的路径。当路径为 ① 根节点到叶节点形成的路径 且 ② 各节点值的和等于目标值 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: return
path.append(root.val)
tar -= root.val
if 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)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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: return
dfs(cur.left) # 递归左子树
if self.pre: # 修改节点引用
self.pre.right, cur.left = cur, self.pre
else: # 记录头节点
self.head = cur
self.pre = cur # 保存 cur
dfs(cur.right) # 递归右子树
if not root: return
self.pre = None
dfs(root)
self.head.left, self.pre.right = self.pre, self.head
return 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
本文解法基于此性质:二叉搜索树的中序遍历为 递增序列 。
根据以上性质,易得二叉搜索树的 中序遍历倒序 为 递减序列 。
因此,求 “二叉搜索树第 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: return
dfs(root.right)
if self.k == 0: return
self.k -= 1
if self.k == 0: self.res = root.val
dfs(root.left)
self.k = k
dfs(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: return
dfs(cur.left)
que.append(cur.val)
dfs(cur.right)
if not root: return None
dfs(root)
print(que)
return que[-k]
2022/3/10
python数据类型
不可变数据类型: 当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,就称不可变数据类型。
**可变数据类型 :**当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型。
数据类型 | 可变/不可变 |
---|---|
整型 | 不可变 |
字符串 | 不可变 |
元组 | 不可变(只可读) |
列表 | 可变 |
集合 | 可变 |
字典 | 可变 |
此题求拼接起来的最小数字,本质上是一个排序问题。设数组 nums中任意两数字的字符串为 x 和 y ,则规定 排序判断规则 为:
若拼接字符串 x+y>y+x ,则 x “大于” y ; [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qfUIRGKj-1648863192597)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220311153752546.png)] 以下两种方法均基于以下性质推出: 此树的深度 等于 左子树的深度 与 右子树的深度 中的 最大值 +1 。 方法一: 后序遍历+剪枝(从底至顶) 思路是对二叉树做后序遍历,从底至顶返回子树深度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6UHhIcV1-1648863192598)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312145701120.png)] 逻辑运算解答 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aFqn2nww-1648863192599)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313105447722.png)] 复杂度分析: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wDGh8o5U-1648863192599)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313110154167.png)] 最近公共祖先的定义: 设节点 root 为节点 p,q 的某公共祖先,若其左子节点 root.left 和右子节点 root.right 都不是 p,q 的公共祖先,则称 root 是 “最近的公共祖先” 。 根据以上定义,若 root 是 p,q 的 最近公共祖先 ,则只可能为以下情况之一: p 和 q 在 root 的子树中,且分列 roott的 异侧(即分别在左、右子树中); [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2p5E2j1-1648863192601)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313114105613.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWpis3co-1648863192602)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313152746920.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mEobju4N-1648863192603)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313152757198.png)] 快速幂法: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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)] 无进位和 与 异或运算 规律相同,进位 和 与运算 规律相同(并需左移一位)。 非进位和:异或运算进位:n=a⊕b 与运算+左移一位: c=a&b<<1 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VNekGoSa-1648863192605)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220317222312585.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5KDktg2-1648863192606)(Leetcode刷题.assets/image-20220321213720186.png)] 双指针/数学求和公式 hash表,set集合,异或。 hash, 摩尔投票法-多数投票法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jDbVSgUY-1648863192606)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312165428719.png)] 排序+双指针 复杂度: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xThokwlz-1648863192606)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312201539941.png)] 输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 分治法 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pGe5loR2-1648863192607)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314100621322.png)] , len(s)): 作者:LeetCode-Solution
反之,若 x+yclass Solution:
def minNumber(self, nums: List[int]) -> str:
def quick_sort(l , r):
if l >= r: return
i, j = l, r
while i < j:
while strs[j] + strs[l] >= strs[l] + strs[j] and i < j: j -= 1
while strs[i] + strs[l] <= strs[l] + strs[i] and i < j: i += 1
strs[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, 14
for num in nums:
if num == 0: continue # 跳过大小王
ma = max(ma, num) # 最大牌
mi = min(mi, num) # 最小牌
if num in repeat: return False # 若有重复,提前返回 false
repeat.add(num) # 添加牌至 Set
return 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 = 0
nums.sort() # 数组排序
for i in range(4):
if nums[i] == 0: joker += 1 # 统计大小王数量
elif nums[i] == nums[i + 1]: return False # 若有重复,提前返回 false
return 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: return
i, j = l, r
while i<j:
while i<j and arr[j]>=arr[l]: j-=1
while 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. 数据流中的中位数
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 = 0
def addNum(self, num: int) -> None:
if not self.length:
self.nums.append(num)
self.length+=1
else:
pos=0
while pos<self.length and self.nums[pos]<=num:
pos+=1
self.nums.insert(pos, num)
self.length+=1
return
def findMedian(self) -> float:
if self.length==0: return self.nums
elif 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 0
return 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 0
queue, res = [root], 0
while queue:
tmp = []
for node in queue:
if node.left: tmp.append(node.left)
if node.right: tmp.append(node.right)
queue = tmp
res += 1
return 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 0
que = collections.deque()
que.append(root)
res = 0
tmp = []
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+=1
for t in tmp:
que.append(t)
tmp = []
* 剑指 Offer 55 - II. 平衡二叉树
#后序遍历+剪枝
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
def recur(root):
if not root: return 0
left = recur(root.left)
if left == -1: return -1
right = recur(root.right)
if right == -1: return -1
return max(left, right) + 1 if abs(left - right) <= 1 else -1
return 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 True
return 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 0
return 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))+1
def maxDiff(root):
if not root: return True
que = []
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 False
if node.left: que.append(node.left)
if node.right: que.append(node.right)
return True
搜索与回溯算法
*剑指 Offer 64. 求1+2+…+n
class Solution:
def __init__(self):
self.res = 0
def sumNums(self, n: int) -> int:
n>1 and self.sumNums(n-1)
self.res+=n
return self.res
剑指 Offer 68 - I. 二叉搜索树的最近公共祖先
p=root,且 q 在 roott 的左或右子树中;
q=root,且 p 在 root 的左或右子树中;#迭代
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
if p.val>q.val: p, q = q, p
while root:
if not root: return root
elif root.val < p.val: root = root.right
elif root.val > q.val: root = root.left
else: break
return root
#递归
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. 二叉搜索树的最近公共祖先
class Solution:
def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
if not root or root == p or root == q: return root
left = 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
剑指 Offer 16. 数值的整数次方
"二分法", "二进制"
class Solution:
def myPow(self, x: float, n: int) -> float:
if x == 0: return 0
res = 1
if n < 0: x, n = 1 / x, -n
while n:
if n & 1: res *= x
x *= x
n >>= 1
return 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=0
while n:
#res += n&1
n>>=1
res+=1
n&=(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
class Solution:
def add(self, a: int, b: int) -> int:
x = 0xffffffff
a, b = a & x, b & x
while b != 0:
a, b = (a ^ b), (a & b) << 1 & x
return 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, 1
for num in nums: # 1. 遍历异或
n ^= num
while n & m == 0: # 2. 循环左移,计算 m
m <<= 1
for num in nums: # 3. 遍历 nums 分组
if num & m: x ^= num # 4. 当 num & m != 0
else: y ^= num # 4. 当 num & m == 0
return 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. 剪绳子
class Solution:
def cuttingRope(self, n: int) -> int:
dp = [0] * (n + 1)
dp[2] = 1
for 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 -= i
i += 1
else:
j += 1
s += j
return 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 = 0
for i in range(2, n + 1):
x = (x + m) % i
return 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
class Solution:
def singleNumber(self, nums: List[int]) -> int:
dic = {}
for n in nums:
dic[n] = 1 if not dic.get(n) else 0
for k in dic.keys():
if dic[k]:res = k
return 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 = 0
for num in nums:
res ^= num
return 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. 多数元素
class Solution:
def majorityElement(self, nums: List[int]) -> int:
count = 0
candidate = None
for num in nums:
if count == 0:
candidate = num
count += (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. 三数之和
class Solution:
def threeSum(self, nums: [int]) -> [[int]]:
nums.sort()
res, k = [], 0
for 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) - 1
while i < j: # 3. double pointer
s = nums[k] + nums[i] + nums[j]
if s < 0:
i += 1
while i < j and nums[i] == nums[i - 1]: i += 1
elif s > 0:
j -= 1
while i < j and nums[j] == nums[j + 1]: j -= 1
else:
res.append([nums[k], nums[i], nums[j]])
i += 1
j -= 1
while i < j and nums[i] == nums[i - 1]: i += 1
while i < j and nums[j] == nums[j + 1]: j -= 1
return res
作者:jyd
链接:https://leetcode-cn.com/problems/3sum/solution/3sumpai-xu-shuang-zhi-zhen-yi-dong-by-jyd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
分治算法(中等)
剑指 Offer 07. 重建二叉树
按照先序顺序构造节点,按照中序划分子树
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 = {}, preorder
for i in range(len(inorder)):
dic[inorder[i]] = i
return 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 = 4
ans = list()
segments = [0] * SEG_COUNT
def 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 地址只能为 0
if s[segStart] == "0":
segments[segId] = 0
dfs(segId + 1, segStart + 1)
# 一般情况,枚举每一种可能性并递归
addr = 0
for segEnd in range(segStart, 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. 全排列
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: continue
nums[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 = -2147483648
str = 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 = False
if len(s)!=0:s = list(s)
else: return 0
if s[0] == "-" or s[0] == "+":
count = 1
for i in range(1,len(s)):
if (s[i]<"0" or s[i]>"9"):break
count+=1
if count!=1: res = ''.join(s[:count])
else:return 0
elif s[0]>="0" and s[0]<="9":
count = 0
for i in range(len(s)):
if (s[i]<"0" or s[i]>"9"):break
count+=1
res = ''.join(s[:count])
else:return 0
if s[0]=="-":
res = max(int(res),pow(-2,31))
return res
elif s[0]=="+":
return min(int(res), pow(2, 31)-1)
else:
return min(int(res), pow(2, 31)-1)
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
链接: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: continue
nums[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 = -2147483648
str = 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 = False
if len(s)!=0:s = list(s)
else: return 0
if s[0] == "-" or s[0] == "+":
count = 1
for i in range(1,len(s)):
if (s[i]<"0" or s[i]>"9"):break
count+=1
if count!=1: res = ''.join(s[:count])
else:return 0
elif s[0]>="0" and s[0]<="9":
count = 0
for i in range(len(s)):
if (s[i]<"0" or s[i]>"9"):break
count+=1
res = ''.join(s[:count])
else:return 0
if s[0]=="-":
res = max(int(res),pow(-2,31))
return res
elif s[0]=="+":
return min(int(res), pow(2, 31)-1)
else:
return min(int(res), pow(2, 31)-1)