收藏:①极市开发DeepLearning ②Git使用

剑指offer 1-66

  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 栈的压入和弹出"""

 

posted @ 2019-08-21 22:04  WSX_1994  阅读(163)  评论(0)    收藏  举报