1 __author__ = "WSX"
2
3 class ListNode:
4 def __init__(self, val):
5 self.val = val
6 self.next = None
7
8 """3\ 19\ 37\ 38 \ 44\ 45\ """
9
10 """
11 1 镜像二叉树: 递归
12 """
13 def mirror(root):
14 if not root:
15 return None
16 mirror(root.left)
17 mirror(root.right)
18 root.left, root.right = root.right, root.left
19 return root
20
21 """2. 链表环入口
22 """
23 def circle(node):
24 if not node:
25 return None
26 slow,fast = node, node
27 while fast and fast.next:
28 slow = slow.next
29 fast = fast.next.next
30 if slow == fast:
31 slow = node
32 while slow != fast:
33 slow = slow.next
34 fast = fast.next
35 return fast
36 return None
37
38 """
39 3 删除重复结点
40 """
41 def delNode(pHead):
42 first = ListNode(-1)
43 cur = pHead
44 last = first
45 while cur and cur.next:
46 if cur.val != cur.next.val:
47 cur = cur.next
48 last = last.next
49 else:
50 val = cur.val
51 while cur and cur.val == val:
52 cur = cur.next
53 last.next = cur
54 return first.next
55
56 """4 打印链表"""
57
58 def info(pHead):
59 res = []
60 if not pHead:
61 return None
62 while pHead:
63 res.index(pHead.val)
64 pHead = pHead.next
65 return res
66
67 """5 斐波那契数列的第n项"""
68
69 def Fib(n):
70 dp = [0,1]
71 if n == 0:
72 return 0
73 if n == 1:
74 return 1
75 for i in range(2, n+1):
76 dp.append(dp[i-1] + dp[i-2])
77 return dp[-1]
78
79 def Fib1(n):
80 if n == 0:
81 return 0
82 if n == 1:
83 return 1
84 a ,b = 0, 1
85 while n-1:
86 temp = a
87 a = b
88 b = temp + b
89 n -= 1
90 return b
91
92 """6 变态跳台阶"""
93 def jump(n):
94 if n == 1:
95 return 1
96 dp = [1]
97 for i in range(1, n):
98 dp[i] = sum(dp[:i]) + 1
99 return dp[-1]
100
101 def jumpFloorII(number):
102 # write code here
103 if number == 1:
104 return 1
105 dp = [1] * (number)
106 dp[0], dp[1] = 1, 2
107 for i in range(2, number):
108 dp[i] = 2 * dp[i - 1]
109 return dp[-1]
110
111 """10 平衡二叉树"""
112
113 def isBalance(root):
114
115 def deep(root):
116 if not root:
117 return 0
118 left = deep(root.left)
119 right = deep(root.right)
120 return max(left, right) + 1
121 if not root:
122 return True
123 return abs(deep(root.left) - deep(root.right)) <=1
124
125 """11.和为s的连续数字"""
126
127 def findNumber(tsum):
128 res = []
129 left, right = 1, 2
130 if tsum < 3:
131 return []
132 while left< right and left < tsum//2+1:
133 if sum(range(left, right+1)) == tsum:
134 res.append(range(left, right+1))
135 left += 1
136 elif sum(range(left, right+1)) < tsum:
137 right +=1
138 else:
139 left+=1
140 return res
141
142 """12 左旋字符串"""
143 def left(s, k):
144 if s == "":
145 return ""
146 k = k%len(s)
147 return s[k:] + s[:k]
148
149 """13 数字在排序数组出现次数"""
150
151 def numberCount(data, k):
152 if not data:
153 return 0
154 left, right = 0, len(data) - 1
155 while left <= right:
156 mid = (left + right) // 2
157 if data[mid] == k:
158 index = mid
159 res = 0
160 while index < len(data) and data[index] == k:
161 res += 1
162 index += 1
163 index = mid - 1
164 while index >= 0 and data[index] == k:
165 res += 1
166 index -= 1
167 return res
168 elif data[mid] > k:
169 right = mid - 1
170 else:
171 left = mid + 1
172 return 0
173
174 """14 数组只出现一次的数字 : 异或运算"""
175
176 def onlyOne(array):
177 temp = 0
178 flag = 1
179 a,b = 0,0
180 for i in array:
181 temp = temp ^ i
182 while temp:
183 if temp % 2 != 0:
184 break
185 temp >> 1
186 flag = flag << 1
187 for i in array:
188 if i&flag:
189 a =a^i
190 else:
191 b = b^i
192 return a,b
193
194 """16 二叉树深度 : 参照10"""
195
196 """17 和为s的两个数: 双指针:距离最远的数字最小"""
197 def FindNumbersWithSum( array, tsum):
198 left, right = 0, len(array)-1
199 a,b = 0,0
200 while left<= right:
201 if array[left] + array[right] == tsum:
202 return array[left],array[right]
203
204 elif array[left] + array[right] < tsum:
205 left +=1
206 else:
207 right -=1
208 return []
209
210 """18 顺时针打印矩阵 : 思路:每次打印第一行,将矩阵逆时针旋转90 直到为None"""
211
212 def infoArray(matrix):
213 if not matrix:
214 return None
215 res = []
216 while matrix:
217 res = res + matrix[0]
218 matrix.pop(0)
219 matrix = list(map(list, zip(*matrix)))[::-1]
220 return res
221
222 """19 二叉树的下一个结点(***)中序遍历(左 中 右)
223 ① 如果结点存在右结点,则进入右子树(最左边的结点) 该节点相当于根
224 ② 若该节点无右子节点,且该节点为父亲的左子节点,则为父节点 该节点为左节点
225 ③ 若该节点无右子节点,且该节点为父亲的右子节点,则需要一直搜索父亲,直到为某个结点的左节点
226
227 """
228 def nextNode(pNode):
229 if not pNode:
230 return None
231 if pNode.right: #情况1
232 temp = pNode.right
233 while temp.left:
234 temp = temp.left
235 return temp
236
237 else:
238 temp = pNode.next #temp指向父亲
239 while temp and temp.right == pNode: #判断是否为父亲的右节点, 不是的话退出 返回上一行的值
240 #是的话执行情况3
241 pNode = temp
242 temp = temp.next
243 return temp
244
245 """20 对称二叉树"""
246
247 def symme(left, right):
248 if not left and not right:
249 return True
250 if left and right:
251 return left.val == right.val and symme(left.left, right.right) and symme(left.right, right.left)
252 else:
253 return False
254 def issymme(pRoot):
255 if not pRoot:
256 return True
257 return symme(pRoot.left, pRoot.right)
258
259 """21 二叉树打印多行 从左往右打印"""
260 """层次遍历二叉树(补充)"""
261 def cengci(root):
262 if not root:
263 return None
264 queue = [root]
265 res = []
266 while queue:
267 res.append(queue[0].val)
268 if queue[0].left:
269 queue.append(queue[0].left)
270 if queue[0].right:
271 queue.append(queue[0].right)
272 queue.pop(0)
273 return res
274
275
276 """本题"""
277 def print(pRoot):
278 if not pRoot:
279 return []
280 res = []
281 queue = [pRoot]
282 while queue:
283 temp = []; queue_temp = []
284 for i in queue:
285 temp.append(i.val)
286 if i.left:
287 queue_temp.append(i.left)
288 if i.right:
289 queue_temp.append(i.right)
290 queue = queue_temp
291 res.append(temp)
292 return res
293 """24 数据流中位数 : 大根堆 和小根堆"""
294
295 """26 重建二叉树 先序 中序"""
296 def buildTree(pre, tin):
297 root = pre[0]
298 index = tin.index(root)
299 ltin = tin[:index]
300 rtin = tin[index+1:]
301 lpre = pre[1:len(ltin)+1]
302 rpre = pre[1+len(ltin):]
303 p = TreeNode(root)
304 p.left = buildTree(lpre,ltin)
305 p.right = buildTree(rpre,rtin)
306 return p
307
308 """27 滑动窗口最大"""
309 def fun(num, size):
310 if len(num) == 0 or size==0 or size>len(num):
311 return []
312
313 res = [] #存储结果
314 queue_index = [] #存储下标
315 for i in range(len(num)):
316 if len(queue_index)>0 and i - size >= queue_index[0]: #超出队列
317 queue_index.pop(0)
318 while len(queue_index) > 0 and num[i] > num[queue_index[-1]]:
319 queue_index.pop()
320 queue_index.append(i)
321
322 if i >= size -1:
323 res.append(num[queue_index[0]])
324 return res
325
326 """28 栈实现队列: 根据性质"""
327
328 """29 旋转数组最小值:二分查找"""
329 def minNumber(rotateArray):
330 if not rotateArray:
331 return None
332 low,high = 0, len(rotateArray)-1
333 while low < high:
334 mid = (low + high) //2
335 if rotateArray[mid] > rotateArray[high]:
336 low = mid + 1
337 else:
338 high = mid
339 return rotateArray[left]
340
341 """30 丑数"""
342 def ugly(index):
343 if index ==0:
344 return 0
345 if index == 1:
346 return 1
347 dp = [1]
348 n1,n2,n3 = 0,0,0
349 for i in range(index-1):
350 num1,num2,num3 = dp[n1]*2, dp[n2]*3, dp[n3]*5
351 Min = min(num1, num2,num3)
352 dp.append(Min)
353 if num1 == Min:
354 n1 += 1
355 if num2 == Min:
356 n2 += 1
357 if num3 == Min:
358 n3 += 1
359 return dp[-1]
360
361 """31 链表的第一个公共结点"""
362 def firstCommonNode(pHead1, pHead2):
363 if not pHead1 or not pHead2:
364 return None
365 p1,p2 = pHead1,pHead2
366 while p1 != p2:
367 if p1:
368 p1 = p1.next
369 else:
370 p1 = pHead2
371 if p2:
372 p2 = p2.next
373 else:
374 p2 = pHead1
375 return p1
376
377 """32 第一次只出现一次的字符
378 queue 存储每个字符第一次出现的位置
379 """
380 def firstChar(s):
381 dict = {}
382 queue = []
383 for i in range(len(s)):
384 if s[i] not in dict:
385 dict[s[i]] = 1
386 queue.append(i)
387 else:
388 dict[s[i]] += 1
389 for i in queue:
390 if dict[s[i]] == 1:
391 return i
392 return -1
393
394 """33 数组中逆序对
395 思路: 先排序 从小到大找 对应 原数组中去
396 例[2,5,1] -> [1,2,5] 从1开始在原数组找它的索引就是它对应的逆序对数 1:2 2:1 5:0
397 """
398 def inverse(data):
399 temp =[]
400 res = 0
401 for i in data:
402 temp.append(i)
403 temp = sorted(temp)
404 for i in temp:
405 res += data.index(i)
406 data.remove(i)
407 return res
408
409 """34 连续数组的最大和"""
410 def FindGreatestSumOfSubArray(array):
411 # write code here
412 for i in range(1, len(array)):
413 if array[i - 1] >= 0:
414 array[i] = array[i] + array[i - 1]
415 else:
416 continue
417 return max(array)
418
419 """35 最小的k个数
420 TOPK问题: 一般建立大根堆, 如果是最大的就建立小根堆
421 快排也可以实现
422 """
423 # 快排
424 def p( L, l, r):
425 temp, i = L[r], l - 1
426 for j in range(l, r):
427 if L[j] <= temp:
428 i += 1
429 L[i], L[j] = L[j], L[i]
430 L[i + 1], L[r] = L[r], L[i + 1]
431 return i + 1
432
433 def GetLeastNumbers_Solution( tinput, k):
434 if k == 0 or k > len(tinput):
435 return []
436 else:
437 flag = p(tinput, 0, len(tinput) - 1) #拆分点
438 while flag != k - 1:
439 if flag > k - 1:
440 flag = p(tinput, 0, flag - 1)
441 if flag < k - 1:
442 flag = p(tinput, flag + 1, len(tinput) - 1)
443 return sorted(tinput[:flag + 1])
444 #堆排序(TOP) 这是找最大的。
445 class Solution:
446 def __init__(self):
447 pass
448 def Heap(self, L, i, size): #小根堆维护
449 root = i
450 left , right = 2*i+1, 2*i+2
451 if left < size and L[root]> L[left]:
452 root = left
453 if right < size and L[root]> L[right]:
454 root = right
455 if root != i:
456 L[root],L[i] = L[i],L[root]
457 self.Heap(L,root,size)
458 return L
459 def buildHeap(self, L):
460 for i in range(len(L)//2,-1,-1):
461 self.Heap(L,i,len(L))
462 return L
463 def TopK(self, L, k):
464 result = L[:k]
465 result = self.buildHeap(result)
466 for i in range(k,len(L)):
467 if L[i] > result[0]:
468 result[0] = L[i]
469 self.Heap(result, 0, k)
470 return result
471 """"""
472
473
474 """36 数组超过一半的数
475 排序(多余一半的肯定出现在中间)"""
476 def MoreNum(numbers):
477 numbers = sorted(numbers)
478 key = numbers[len(numbers) // 2]
479 if numbers.count(key) > len(numbers) // 2:
480 return key
481 else:
482 return 0
483
484 """37 1 到n中 1出现的次数
485 找规律
486 """
487 """38 数组排成最小的数"""
488 def minNum(numbers):
489 if numbers is None or len(numbers) == 0:
490 return ""
491 numbers = map(str, numbers)
492 numbers.sort(cmp=lambda x, y: cmp(x + y, y + x))
493 return "".join(numbers).lstrip()
494
495 #错误
496 def minNum2(numbers):
497 numbers = sorted(list(map(str, numbers)))
498 res = ""
499 for i in numbers:
500 print(i)
501 if (res + i) >= (i + res):
502 res = i+res
503 else:
504 res = res+i
505
506 return res
507
508 """39 数组中重复的数字"""
509 def duplicate(numbers, duplication):
510 # write code here
511 dict = {}
512 for i in range(len(numbers)):
513 if numbers[i] not in dict:
514 dict[numbers[i]] = 1
515 else:
516 dict[numbers[i]] += 1
517 for i in dict:
518 if dict[i] > 1:
519 duplication[0] = i
520 return True
521 duplication[0] = -1
522 return False
523
524 """40 构造乘积数组
525 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],
526 其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。
527 """
528 def mulMatrix(A):
529 size = len(A)
530 B = [1] * size
531 for i in range(1, size): # 构建下三角矩阵(上 到 下)
532 B[i] = A[i - 1] * B[i - 1]
533 temp = 1
534 for i in range(size - 2, -1, -1):
535 temp = temp * A[i + 1]
536 B[i] = B[i] * temp
537 return B
538
539 """?? 旋转数组的查找:二分查找"""
540 def findKey(target, array):
541 if not array:
542 return None
543 left, right = 0,len(array)-1
544 while left < right:
545 mid = (left + right)//2
546 if array[mid] == target:
547 return True
548 if array[mid] < array[right]: #右侧有序
549 if target > array[mid] and target <= array[right]:
550 left = mid + 1
551 else:
552 right = mid -1
553 else:
554 if target >= array[left] and target < array[mid]:
555 right = mid -1
556 else:
557 left = mid + 1
558 return False
559
560 """41 二维数组的查找"""
561 def findkey(target, array):
562 if not array:
563 return False
564 row ,col = 0, len(array[0])-1
565 while row <= len(array) and col>=0:
566 if array[row][col] == target:
567 return True
568 elif array[row][col] > target:
569 col -= 1
570 else:
571 row += 1
572 return False
573
574
575 """42 扑克牌顺子"""
576 def IsContinuous( numbers):
577 if not numbers:
578 return False
579 numbers = sorted(numbers)
580 count = 0
581 for i in range(len(numbers) - 1, 0, -1):
582 if numbers[i - 1] != 0:
583 if numbers[i] == numbers[i - 1]:
584 return False
585 count = count + numbers[i] - numbers[i - 1] - 1
586 else:
587 count -= 1
588 if count <= 0:
589 return True
590 else:
591 return False
592
593 """43 孩子们的游戏"""
594 def LastRemaining_Solution(n, m):
595 start = 0
596 final = -1
597 L = [i for i in range(n)]
598 while L:
599 temp = (m-1+start)%n
600 final = L.pop(temp)
601 n-=1
602 start = temp
603 return final
604
605 """44 正则表达式匹配"""
606
607 """45 字符串表示字符"""
608 def isNumeric(s):
609 pass
610
611 """46 字符流中第一个不重复的字符 前面做过"""
612 """47 替换空格 replace(" ", "%20")"""
613
614 """48 矩阵中的路径"""
615
616
617 """49 机器人运动范围 思想:均是访问过标志位为1"""
618 class Solution49_1:
619 def judge(self, threshold, i, j): #判断是否合法的坐标
620 if sum(map(int,str(i)+str(j))) <= threshold:
621 return True
622 else:
623 return False
624
625 def findgrid(self, threshold, rows, cols, matrix, i, j):
626 count = 0
627 if i<rows and j<cols and i>=0 and j>=0 and self.judge(threshold,i,j) and matrix[i][j]==0:
628 matrix[i][j] = 1 #标志位0 为未访问 1 为访问
629 count = 1 + self.findgrid(threshold, rows, cols, matrix, i, j+1) \
630 + self.findgrid(threshold, rows, cols, matrix, i, j-1) \
631 + self.findgrid(threshold, rows, cols, matrix, i+1, j) \
632 + self.findgrid(threshold, rows, cols, matrix, i-1, j)
633 return count
634
635 def movingCount(self, threshold, rows, cols):
636 # write code here
637 matrix = [[0 for i in range(cols)] for j in range(rows)]
638 count = self.findgrid(threshold, rows, cols, matrix, 0, 0)
639 #print(matrix)
640 return count
641
642 """岛屿数量"""
643 class Solution49_2:
644 def numIslands(self, grid):
645 if not grid:
646 return 0
647 row, col = len(grid), len(grid[0])
648 res = 0
649 for i in range(row):
650 for j in range(col):
651 if grid[i][j] == "1":
652 res += 1
653 self.intozero(grid, i, j)
654 return res
655 def intozero(self, grid, i, j):
656 grid[i][j] = "0"
657 if i > 0 and grid[i - 1][j] == "1":
658 self.intozero(grid, i - 1, j)
659 if j > 0 and grid[i][j - 1] == "1":
660 self.intozero(grid, i, j - 1)
661 if i < len(grid) - 1 and grid[i + 1][j] == "1":
662 self.intozero(grid, i + 1, j)
663 if j < len(grid[0]) - 1 and grid[i][j + 1] == "1":
664 self.intozero(grid, i, j + 1)
665
666 class Solution49_3:
667 def draw(self, grid, x, y):
668 l = len(grid)
669 h = len(grid[0])
670 if 0 <= x < l and 0 <= y < h :
671 if grid[x][y] == '1':
672 grid[x][y] = '0'
673 self.draw(grid, x - 1, y)
674 self.draw(grid, x, y + 1)
675 self.draw(grid, x + 1, y)
676 self.draw(grid, x, y -1)
677 def numIslands(self, grid ) -> int:
678 re = 0
679 for i in range(len(grid)):
680 for j in range(len(grid[0])):
681 if grid[i][j] == '1':
682 re = re + 1
683 self.draw(grid, i, j)
684 return re
685 """50 1+2+3+....n"""
686 """51 不用加减乘除加法"""
687 def Add(num1, num2):
688 carry = num1 & num2
689 add = num1 ^ num2
690 while carry:
691 num1 = add
692 num2 = carry <<1
693 carry = num1 & num2
694 add = num1 ^ num2
695 return num1
696
697 """52 二叉搜索树和双向链表"""
698 """53 复杂链表复制"""
699 #encoding:utf8
700 class RandomListNode():
701 def __init__(self,x):
702 self.label = x
703 self.next = None
704 self.random = None
705 class Solution:
706 def clone(pHead):
707 if pHead == None:
708 return None
709 #复制节点在原节点之后
710 pCur = pHead
711 while(pCur != None):
712 node = RandomListNode(pCur.label)
713 node.next = pCur.next
714 pCur.next = node
715 pCur = node.next
716 #复制random节点
717 pCur = pHead
718 while(pCur != None):
719 if pCur.random != None:
720 pCur.next.random = pCur.random.next
721 pCur = pCur.next.next
722 head = pHead.next
723 cur = head
724 #将新旧链表分离
725 pCur = pHead
726 while(pCur != None):
727 pCur.next = pCur.next.next
728 if cur.next != None:
729 cur.next = cur.next.next
730 cur = cur.next
731 pCur = pCur.next
732 return head
733
734 """54 字符串排列"""
735 def Permutation( ss):
736 if not ss:
737 return []
738 if len(ss) == 1:
739 return [ss]
740 res = []
741 for i in range(len(ss)):
742 temp = Permutation(ss[:i] + ss[i+1:])
743 for j in temp:
744 res.append(ss[i] +j)
745 return sorted(set(res))
746
747 """55 二进制1个数"""
748 def NumberOf1( n):
749 count = 0
750 if n < 0:
751 n = n&0xffffffff
752 while n:
753 n = n&(n-1)
754 count += 1
755 return count
756
757 """56 链表倒数k各节点:快慢指针"""
758 def FindKthToTail(head, k):
759 if not head:
760 return None
761
762 fast, slow = head, head
763 while k:
764 if fast:
765 fast = fast.next
766 k -= 1
767 else:
768 return None
769 while fast:
770 slow = slow.next
771 fast = fast.next
772 return slow
773
774 """57 合并有序链表"""
775 def Merge(pHead1, pHead2):
776 p1, p2 = pHead1, pHead2
777 head = ListNode(-1)
778 temp = head
779 while p1 and p2:
780 if p1.val < p2.val:
781 temp.next = p1
782 p1 = p1.next
783 else:
784 temp.next = p2
785 p2 = p2.next
786 temp = temp.next
787 if p1:
788 temp.next = p1
789 if p2:
790 temp.next = p2
791 return head.next
792
793 """58 反转链表"""
794 def ReverseList(pHead):
795 if not pHead:
796 return None
797 last = None
798 while pHead:
799 temp = pHead.next
800 pHead.next = last
801 last = pHead
802 pHead = temp
803 return last
804
805 """59 B是否为A的子结构"""
806
807
808 """60 数值的n次方"""
809 def Power(base, exponent):
810 if base == 0:
811 return 0
812 if exponent == 0:
813 return 1
814 if exponent > 0:
815 result = 1
816 for i in range(exponent):
817 result = result * base
818 return result
819 if exponent < 0:
820 result = 1
821 for i in range(-exponent):
822 result = result * base
823 return 1 / result
824
825 """61 奇数位于偶数前"""
826
827
828 def reOrderArray(array):
829 # write code here
830 left = [];
831 right = []
832 for i in range(len(array)):
833 if array[i] % 2 != 0:
834 left.append(array[i])
835 else:
836 right.append(array[i])
837 return left + right
838
839 """62 包含min的栈"""
840
841 """63 二叉树某和路径"""
842 def FindPath(root, expectNumber):
843 # write code here
844 result = []
845 if not root:
846 return []
847 if root.left == None and root.right == None:
848 if root.val == expectNumber:
849 return [[root.val]]
850 else:
851 return []
852 else:
853
854 left = FindPath(root.left, expectNumber - root.val)
855 right = FindPath(root.right, expectNumber - root.val)
856 for i in left + right:
857 result.append([root.val] + i)
858 return result
859
860 """64 层次打印二叉树"""
861
862
863 """65 二叉搜索树后序"""
864
865
866 """66 栈的压入和弹出"""