classSolution: defreverseList(self, head: ListNode) -> ListNode: if head isNone:return head re=[] while head: re.append(head) temp=head.next head.next=None head=temp re.reverse() print(re) ret=None for i inrange(len(re)): if ret isNone: ret=re[i] else: ret.next=re[i] ret=ret.next return re[0]
# 拼接+拆分 classSolution: defcopyRandomList(self, head: 'Node') -> 'Node': if head isNone :returnNone temphead=head while head: temp=Node(head.val) temp.next=head.next head.next=temp head=head.next.next head=temphead while head: if head.random: head.next.random=head.random.next head=head.next.next orighead=head=temphead.next ans=head while head: if head.nextisNone: break temp=orighead.next.next head.next=orighead.next.next head=head.next orighead=temp return ans
classSolution: defminArray(self, numbers: List[int]) -> int: for i inrange(1,len(numbers)): if numbers[i]<numbers[i-1]: return numbers[i] return numbers[0]
classSolution: deffirstUniqChar(self, s: str) -> str: m=OrderedDict() for i in s: m[i]=m.get(i,0)+1 for k,v in m.items(): if v==1: return k return' ' # frequency = collections.Counter(s) # for i, ch in enumerate(s): # if frequency[ch] == 1: # return ch # return ' '
classSolution: defisSymmetric(self, root: TreeNode) -> bool: defcheck(a,b): if a isNoneand b isNone: returnTrue if a isNoneand b : returnFalse if b isNoneand a: returnFalse if a.val != b.val: returnFalse return check(a.left,b.right) and check(a.right,b.left) return check(root,root)
classSolution: defmaxValue(self, grid: List[List[int]]) -> int: # n=len(grid) # m=len(grid[0]) # dp=[[0]*m for _ in range(n)] # dp[0][0]=grid[0][0] # for i in range(1,n): # dp[i][0]=dp[i-1][0]+grid[i][0] # for i in range(1,m): # dp[0][i]=dp[0][i-1]+grid[0][i] # for i in range(1,n): # for j in range(1,m): # dp[i][j]=max(dp[i-1][j],dp[i][j-1])+grid[i][j] # return dp[n-1][m-1] m, n = len(grid), len(grid[0]) for j inrange(1, n): # 初始化第一行 grid[0][j] += grid[0][j - 1] for i inrange(1, m): # 初始化第一列 grid[i][0] += grid[i - 1][0] for i inrange(1, m): for j inrange(1, n): grid[i][j] += max(grid[i][j - 1], grid[i - 1][j]) return grid[-1][-1]
classSolution: deftranslateNum(self, num: int) -> int: num=str(num) length=len(num) if length==1: return1 a=1 b=0 ifint(num[0])*10+int(num[1])<=25andint(num[0])*10!=0: b=2 else: b=1 for index,item inenumerate(num[2:],2): ifint(num[index-1])*10+int(num[index])<=25andint(num[index-1])*10!=0: b,a=a+b,b else: b,a=b,b return b ''' s = str(num) a = b = 1 for i in range(2, len(s) + 1): tmp = s[i - 2:i] c = a + b if "10" <= tmp <= "25" else a b = a a = c return a '''
classSolution: defgetIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: pA,pB=headA,headB while pA or pB: if pA==pB: return pA if pA: pA=pA.next else: pA=headB if pB: pB=pB.next else: pB=headA returnNone
defdfs(cur,x,y): if board[x][y]!=word[cur]: returnFalse if cur==length-1: returnTrue for i,j in [(1,0),(-1,0),(0,1),(0,-1)]: x_,y_=x+i,y+j if0<=x_<n and0<=y_<m andnot visited[x_][y_]: visited[x_][y_]=1 if dfs(cur+1,x_,y_): returnTrue visited[x_][y_]=0 returnFalse for i inrange(n): for j inrange(m): if board[i][j]==word[0]: visited[i][j]=1 if dfs(0,i,j): returnTrue visited[i][j]=0 returnFalse
classSolution: defmovingCount(self, m: int, n: int, k: int) -> int: defcheck(a,b): t=0 for num in chain(str(a),str(b)): t+=int(num) if t<=k: returnTrue returnFalse # visited={} # ans=0 # def dfs(x,y): # for i,j in [(1,0),(-1,0),(0,1),(0,-1)]: # x_,y_=x+i,y+j # if 0<=x_<n and 0<=y_<m and (x_,y_) not in visited: # visited[(x_,y_)]=1 # if check(x_,y_): # nonlocal ans # ans+=1 # dfs(x_,y_) # if k>=0: # ans+=1 # visited[(0,0)]=1 # dfs(0,0) # return ans visited={} visited[(0,0)]=1 for i inrange(n): for j inrange(m): if ((i-1,j) in visited or (i,j-1) in visited) : if check(i,j): visited[(i,j)]=1 returnlen(visited)
classSolution: defkthLargest(self, root: TreeNode, k: int) -> int: cnt=0 ans=-1 defdfs(curnode): # s起点,e终点 nonlocal cnt if cnt>k:return if curnode.right: dfs(curnode.right) if cnt+1==k: nonlocal ans ans=curnode.val cnt+=1 if cnt>k:return if curnode.left: dfs(curnode.left) dfs(root) return ans
classSolution: defisStraight(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: returnFalse# 若有重复,提前返回 false repeat.add(num) # 添加牌至 Set return ma - mi < 5# 最大牌 - 最小牌 < 5 则可构成顺子
classSolution: defgetLeastNumbers(self, arr: List[int], k: int) -> List[int]: # if k==0:return [] # a=[-arr[i] for i in range(k)] # heapq.heapify(a) # for item in arr[k:]: # if -item > a[0]: # heapq.heappushpop(a,-item) # return list(map(lambda x:-x,a)) if k==0:return [] if k>=len(arr):return arr defquick_sort(l,r): 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[i],arr[l]=arr[l],arr[i] if k<i:return quick_sort(l,i-1) if k>i:return quick_sort(i+1,r) return arr[:k] return quick_sort(0,len(arr)-1)
while que: length=len(que) for i inrange(length): cur=que.popleft() if cur.left: que.append(cur.left) if cur.right: que.append(cur.right) ans+=1 return ans
classSolution: ans=None deflowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode: # def dfs(cur): # if not cur :return False # left=dfs(cur.left) # right=dfs(cur.right) # if (left and right) or ((left or right) and (cur==p or cur == q)): # self.ans=cur # return left or right or cur==p or cur == q # dfs(root) # return self.ans fa={} defdfs(cur): if cur.left: fa[cur.left.val]=cur dfs(cur.left) if cur.right: fa[cur.right.val]=cur dfs(cur.right) fa[root.val]=None dfs(root) vis={} while p: vis[p]=1 p=fa[p.val] while q: if q in vis: return q q=fa[q.val] returnNone
classSolution: defmyPow(self, x: float, n: int) -> float: res = 1 if n>0: while n > 0: if n & 1: res *= x x *= x n >>= 1 else: n=abs(n) while n > 0: if n & 1: res /= x x *= x n >>= 1 return res
classSolution: defadd(self, a: int, b: int) -> int: a %= MASK1 b %= MASK1 while b != 0: carry = ((a & b) << 1) % MASK1 a = (a ^ b) % MASK1 b = carry if a & MASK2: # 负数 return ~((a ^ MASK2) ^ MASK3) else: # 正数 return a
第二十二天
剑指 Offer 56 - I. 数组中数字出现的次数
思路:两个相同的数异或为0,但是数据里面有两个只出现一次的数,把数据全部异或一遍之后,结果就是这两个数异或的结果,从后往前遍历这个结果,遇见的第一个1,就是这两个数不同的位置,然后根据这个位置把数组分成两份,这两份里面的数字异或完就剩下只出现一次的数字
classSolution: defsingleNumber(self, nums: List[int]) -> int: counts = [0] * 32 for num in nums: for j inrange(32): counts[j] += num & 1 num >>= 1 counts=list(map(lambda x:x%3,counts)) ans=0 for j inrange(32): if counts[j]: temp=1<<j ans^=temp return ans
classSolution: defmajorityElement(self, nums: List[int]) -> int: votes = 0 for num in nums: if votes == 0: x = num votes += 1if num == x else -1 # 验证 x 是否为众数 # for num in nums: # if num == x: count += 1 # return x if count > len(nums) // 2 else 0 # 当无众数时返回 0 return x
classSolution: defspiralOrder(self, matrix:[[int]]) -> [int]: ifnot matrix: return [] l, r, t, b, res = 0, len(matrix[0]) - 1, 0, len(matrix) - 1, [] whileTrue: for i inrange(l, r + 1): res.append(matrix[t][i]) # left to right t += 1 if t > b: break for i inrange(t, b + 1): res.append(matrix[i][r]) # top to bottom r -= 1 if l > r: break for i inrange(r, l - 1, -1): res.append(matrix[b][i]) # right to left b -= 1 if t > b: break for i inrange(b, t - 1, -1): res.append(matrix[i][l]) # bottom to top l += 1 if l > r: break return res
classSolution: defmaxSlidingWindow(self, nums: List[int], k: int) -> List[int]: deq=MaxQueue() for item in nums[:k-1]: deq.push_back(item) ans=[] for item in nums[k-1:]: deq.push_back(item) ans.append(deq.max_value()) deq.pop_front() return ans
dp[i-1][j] and ‘*’==p[j-1]: *前面的字符是.,随意匹配 (这两种情况可以视作,当前的p和s已经匹配了,s又加入了一个新字符,看这个新字符和p的最后一个是不是一样)
当p[j]!='*'时:
dp[i-1][j-1] and s[i-1]==p[j-1]:前面的都能匹配,看当前位置的两个字符是不是一样
dp[i-1][j-1] and ‘.’==p[j-1]: .随意匹配
实现的时候注意,dp的下标是从1开始,但是s,p的下标是从0开始,公式里面的sp下标要多减个1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution: defisMatch(self, s: str, p: str) -> bool: m, n = len(s) + 1, len(p) + 1 dp = [[False] * n for _ inrange(m)] dp[0][0] = True for j inrange(2, n, 2): dp[0][j] = dp[0][j - 2] and p[j - 1] == '*' for i inrange(1,m): for j inrange(1,n): if p[j-1]=='*': if dp[i][j-2] or ( s[i-1]==p[j-2] and dp[i-1][j]) or ( p[j-2]=='.'and dp[i-1][j]): dp[i][j]=True else: if ( p[j-1]=='.'and dp[i-1][j-1]) or (( p[j-1]==s[i-1] and dp[i-1][j-1])): dp[i][j]=True
classSolution: defdicesProbability(self, n: int) -> List[float]: dp=[[0]*(5*(n+1)+1) for _ inrange(n+1)] for k inrange(6): dp[1][k]=1/6 for i inrange(2,n+1): for j inrange(5*i+1): for k inrange(6): dp[i][j+k]+=(dp[i-1][j])/6 print(dp) return dp[n][:5*n+1]
defmerge(left, right): """合并两个已排序好的列表,产生一个新的已排序好的列表""" result = [] # 新的已排序好的列表 i = 0# 下标 j = 0 # 对两个列表中的元素 两两对比。 # 将最小的元素,放到result中,并对当前列表下标加1 while i < len(left) and j < len(right): # 左边的小,正常 if left[i] <= right[j]: result.append(left[i]) i += 1 # 右边的小 ,是逆序,并且左边的往后也构成逆序 else: result.append(right[j]) j += 1 nonlocal ans ans+=len(left)-i result += left[i:] result += right[j:] return result mergesort(nums) return ans
classSolution: defcuttingRope(self, n: int) -> int: if n==2:return1 if n==3:return2 if n==4:return4 MOD=1e9+7 ans=1 while n>4: ans*=3 n-=3 ans%=MOD returnint((ans*n)%MOD)