今天主要写了一下offer 1-41题,余下的稍后整理
1 """
2 1 镜像二叉树: 递归
3 """
4 def mirror(root):
5 if not root:
6 return None
7 mirror(root.left)
8 mirror(root.right)
9 root.left, root.right = root.right, root.left
10 return root
11
12 """2. 链表环入口
13 """
14 def circle(node):
15 if not node:
16 return None
17 slow,fast = node, node
18 while fast and fast.next:
19 slow = slow.next
20 fast = fast.next.next
21 if slow == fast:
22 slow = node
23 while slow != fast:
24 slow = slow.next
25 fast = fast.next
26 return fast
27 return None
28
29 """
30 3 删除重复结点
31 """
32 def delNode(pHead):
33 first = ListNode(-1)
34 cur = pHead
35 last = first
36 while cur and cur.next:
37 if cur.val != cur.next.val:
38 cur = cur.next
39 last = last.next
40 else:
41 val = cur.val
42 while cur and cur.val == val:
43 cur = cur.next
44 last.next = cur
45 return first.next
46
47 """4 打印链表"""
48
49 def info(pHead):
50 res = []
51 if not pHead:
52 return None
53 while pHead:
54 res.index(pHead.val)
55 pHead = pHead.next
56 return res
57
58 """5 斐波那契数列的第n项"""
59
60 def Fib(n):
61 dp = [0,1]
62 if n == 0:
63 return 0
64 if n == 1:
65 return 1
66 for i in range(2, n+1):
67 dp.append(dp[i-1] + dp[i-2])
68 return dp[-1]
69
70 def Fib1(n):
71 if n == 0:
72 return 0
73 if n == 1:
74 return 1
75 a ,b = 0, 1
76 while n-1:
77 temp = a
78 a = b
79 b = temp + b
80 n -= 1
81 return b
82
83 """6 变态跳台阶"""
84 def jump(n):
85 if n == 1:
86 return 1
87 dp = [1]
88 for i in range(1, n):
89 dp[i] = sum(dp[:i]) + 1
90 return dp[-1]
91
92 def jumpFloorII(number):
93 # write code here
94 if number == 1:
95 return 1
96 dp = [1] * (number)
97 dp[0], dp[1] = 1, 2
98 for i in range(2, number):
99 dp[i] = 2 * dp[i - 1]
100 return dp[-1]
101
102 """10 平衡二叉树"""
103
104 def isBalance(root):
105
106 def deep(root):
107 if not root:
108 return 0
109 left = deep(root.left)
110 right = deep(root.right)
111 return max(left, right) + 1
112 if not root:
113 return True
114 return abs(deep(root.left) - deep(root.right)) <=1
115
116 """11.和为s的连续数字"""
117
118 def findNumber(tsum):
119 res = []
120 left, right = 1, 2
121 if tsum < 3:
122 return []
123 while left< right and left < tsum//2+1:
124 if sum(range(left, right+1)) == tsum:
125 res.append(range(left, right+1))
126 left += 1
127 elif sum(range(left, right+1)) < tsum:
128 right +=1
129 else:
130 left+=1
131 return res
132
133 """12 左旋字符串"""
134 def left(s, k):
135 if s == "":
136 return ""
137 k = k%len(s)
138 return s[k:] + s[:k]
139
140 """13 数字在排序数组出现次数"""
141
142 def numberCount(data, k):
143 if not data:
144 return 0
145 left, right = 0, len(data) - 1
146 while left <= right:
147 mid = (left + right) // 2
148 if data[mid] == k:
149 index = mid
150 res = 0
151 while index < len(data) and data[index] == k:
152 res += 1
153 index += 1
154 index = mid - 1
155 while index >= 0 and data[index] == k:
156 res += 1
157 index -= 1
158 return res
159 elif data[mid] > k:
160 right = mid - 1
161 else:
162 left = mid + 1
163 return 0
164
165 """14 数组只出现一次的数字 : 异或运算"""
166
167 def onlyOne(array):
168 temp = 0
169 flag = 1
170 a,b = 0,0
171 for i in array:
172 temp = temp ^ i
173 while temp:
174 if temp % 2 != 0:
175 break
176 temp >> 1
177 flag = flag << 1
178 for i in array:
179 if i&flag:
180 a =a^i
181 else:
182 b = b^i
183 return a,b
184
185 """16 二叉树深度 : 参照10"""
186
187 """17 和为s的两个数: 双指针:距离最远的数字最小"""
188 def FindNumbersWithSum( array, tsum):
189 left, right = 0, len(array)-1
190 a,b = 0,0
191 while left<= right:
192 if array[left] + array[right] == tsum:
193 return array[left],array[right]
194
195 elif array[left] + array[right] < tsum:
196 left +=1
197 else:
198 right -=1
199 return []
200
201 """18 顺时针打印矩阵 : 思路:每次打印第一行,将矩阵逆时针旋转90 直到为None"""
202
203 def infoArray(matrix):
204 if not matrix:
205 return None
206 res = []
207 while matrix:
208 res = res + matrix[0]
209 matrix.pop(0)
210 matrix = list(map(list, zip(*matrix)))[::-1]
211 return res
212
213 """19 二叉树的下一个结点(***)中序遍历(左 中 右)
214 ① 如果结点存在右结点,则进入右子树(最左边的结点) 该节点相当于根
215 ② 若该节点无右子节点,且该节点为父亲的左子节点,则为父节点 该节点为左节点
216 ③ 若该节点无右子节点,且该节点为父亲的右子节点,则需要一直搜索父亲,直到为某个结点的左节点
217
218 """
219 def nextNode(pNode):
220 if not pNode:
221 return None
222 if pNode.right: #情况1
223 temp = pNode.right
224 while temp.left:
225 temp = temp.left
226 return temp
227
228 else:
229 temp = pNode.next #temp指向父亲
230 while temp and temp.right == pNode: #判断是否为父亲的右节点, 不是的话退出 返回上一行的值
231 #是的话执行情况3
232 pNode = temp
233 temp = temp.next
234 return temp
235
236 """20 对称二叉树"""
237
238 def symme(left, right):
239 if not left and not right:
240 return True
241 if left and right:
242 return left.val == right.val and symme(left.left, right.right) and symme(left.right, right.left)
243 else:
244 return False
245 def issymme(pRoot):
246 if not pRoot:
247 return True
248 return symme(pRoot.left, pRoot.right)
249
250 """21 二叉树打印多行 从左往右打印"""
251 """层次遍历二叉树(补充)"""
252 def cengci(root):
253 if not root:
254 return None
255 queue = [root]
256 res = []
257 while queue:
258 res.append(queue[0].val)
259 if queue[0].left:
260 queue.append(queue[0].left)
261 if queue[0].right:
262 queue.append(queue[0].right)
263 queue.pop(0)
264 return res
265
266
267 """本题"""
268 def print(pRoot):
269 if not pRoot:
270 return []
271 res = []
272 queue = [pRoot]
273 while queue:
274 temp = []; queue_temp = []
275 for i in queue:
276 temp.append(i.val)
277 if i.left:
278 queue_temp.append(i.left)
279 if i.right:
280 queue_temp.append(i.right)
281 queue = queue_temp
282 res.append(temp)
283 return res
284 """24 数据流中位数 : 大根堆 和小根堆"""
285
286 """26 重建二叉树 先序 中序"""
287 def buildTree(pre, tin):
288 root = pre[0]
289 index = tin.index(root)
290 ltin = tin[:index]
291 rtin = tin[index+1:]
292 lpre = pre[1:len(ltin)+1]
293 rpre = pre[1+len(ltin):]
294 p = TreeNode(root)
295 p.left = buildTree(lpre,ltin)
296 p.right = buildTree(rpre,rtin)
297 return p
298
299 """27 滑动窗口最大"""
300
301 """28 栈实现队列: 根据性质"""
302
303 """29 旋转数组最小值:二分查找"""
304 def minNumber(rotateArray):
305 if not rotateArray:
306 return None
307 low,high = 0, len(rotateArray)-1
308 while low < high:
309 mid = (low + high) //2
310 if rotateArray[mid] > rotateArray[high]:
311 left = mid + 1
312 else:
313 high = mid
314 return rotateArray[left]
315
316 """30 丑数"""
317 def ugly(index):
318 if index ==0:
319 return 0
320 if index == 1:
321 return 1
322 dp = [1]
323 n1,n2,n3 = 0,0,0
324 for i in range(index-1):
325 num1,num2,num3 = dp[n1]*2, dp[n2]*3, dp[n3]*5
326 Min = min(num1, num2,num3)
327 dp.append(Min)
328 if num1 == Min:
329 n1 += 1
330 if num2 == Min:
331 n2 += 1
332 if num3 == Min:
333 n3 += 1
334 return dp[-1]
335
336 """31 链表的第一个公共结点"""
337 def firstCommonNode(pHead1, pHead2):
338 if not pHead1 or not pHead2:
339 return None
340 p1,p2 = pHead1,pHead2
341 while p1 != p2:
342 if p1:
343 p1 = p1.next
344 else:
345 p1 = pHead2
346 if p2:
347 p2 = p2.next
348 else:
349 p2 = pHead1
350 return p1
351
352 """32 第一次只出现一次的字符
353 queue 存储每个字符第一次出现的位置
354 """
355 def firstChar(s):
356 dict = {}
357 queue = []
358 for i in range(len(s)):
359 if s[i] not in dict:
360 dict[s[i]] = 1
361 queue.append(i)
362 else:
363 dict[s[i]] += 1
364 for i in queue:
365 if dict[s[i]] == 1:
366 return i
367 return -1
368
369 """33 数组中逆序对
370 思路: 先排序 从小到大找 对应 原数组中去
371 例[2,5,1] -> [1,2,5] 从1开始在原数组找它的索引就是它对应的逆序对数 1:2 2:1 5:0
372 """
373 def inverse(data):
374 temp =[]
375 res = 0
376 for i in data:
377 temp.append(i)
378 temp = sorted(temp)
379 for i in temp:
380 res += data.index(i)
381 data.remove(i)
382 return res
383
384 """34 连续数组的最大和"""
385 def FindGreatestSumOfSubArray(array):
386 # write code here
387 for i in range(1, len(array)):
388 if array[i - 1] >= 0:
389 array[i] = array[i] + array[i - 1]
390 else:
391 continue
392 return max(array)
393
394 """35 最小的k个数
395 TOPK问题: 一般建立大根堆, 如果是最大的就建立小根堆
396 快排也可以实现
397 """
398 # 快排
399 def p( L, l, r):
400 temp, i = L[r], l - 1
401 for j in range(l, r):
402 if L[j] <= temp:
403 i += 1
404 L[i], L[j] = L[j], L[i]
405 L[i + 1], L[r] = L[r], L[i + 1]
406 return i + 1
407
408 def GetLeastNumbers_Solution( tinput, k):
409 if k == 0 or k > len(tinput):
410 return []
411 else:
412 flag = p(tinput, 0, len(tinput) - 1) #拆分点
413 while flag != k - 1:
414 if flag > k - 1:
415 flag = p(tinput, 0, flag - 1)
416 if flag < k - 1:
417 flag = p(tinput, flag + 1, len(tinput) - 1)
418 return sorted(tinput[:flag + 1])
419 #堆排序(TOP) 这是找最大的。
420 class Solution:
421 def __init__(self):
422 pass
423 def Heap(self, L, i, size): #小根堆维护
424 root = i
425 left , right = 2*i+1, 2*i+2
426 if left < size and L[root]> L[left]:
427 root = left
428 if right < size and L[root]> L[right]:
429 root = right
430 if root != i:
431 L[root],L[i] = L[i],L[root]
432 self.Heap(L,root,size)
433 return L
434 def buildHeap(self, L):
435 for i in range(len(L)//2,-1,-1):
436 self.Heap(L,i,len(L))
437 return L
438 def TopK(self, L, k):
439 result = L[:k]
440 result = self.buildHeap(result)
441 for i in range(k,len(L)):
442 if L[i] > result[0]:
443 result[0] = L[i]
444 self.Heap(result, 0, k)
445 return result
446 """"""
447
448
449 """36 数组超过一半的数
450 排序(多余一半的肯定出现在中间)"""
451 def MoreNum(numbers):
452 numbers = sorted(numbers)
453 key = numbers[len(numbers) // 2]
454 if numbers.count(key) > len(numbers) // 2:
455 return key
456 else:
457 return 0
458
459 """37 1 到n中 1出现的次数
460 找规律
461 """
462 """38 数组排成最小的数"""
463 def minNum(numbers):
464 if numbers is None or len(numbers) == 0:
465 return ""
466 numbers = map(str, numbers)
467 numbers.sort(cmp=lambda x, y: cmp(x + y, y + x))
468 return "".join(numbers).lstrip()
469
470 #错误
471 def minNum2(numbers):
472 numbers = sorted(list(map(str, numbers)))
473 res = ""
474 for i in numbers:
475 print(i)
476 if (res + i) >= (i + res):
477 res = i+res
478 else:
479 res = res+i
480
481 return res
482
483 """39 数组中重复的数字"""
484 def duplicate(numbers, duplication):
485 # write code here
486 dict = {}
487 for i in range(len(numbers)):
488 if numbers[i] not in dict:
489 dict[numbers[i]] = 1
490 else:
491 dict[numbers[i]] += 1
492 for i in dict:
493 if dict[i] > 1:
494 duplication[0] = i
495 return True
496 duplication[0] = -1
497 return False
498
499 """40 构造乘积数组
500 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],
501 其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。
502 """
503 def mulMatrix(A):
504 size = len(A)
505 B = [1] * size
506 for i in range(1, size): # 构建下三角矩阵(上 到 下)
507 B[i] = A[i - 1] * B[i - 1]
508 temp = 1
509 for i in range(size - 2, -1, -1):
510 temp = temp * A[i + 1]
511 B[i] = B[i] * temp
512 return B
513
514 """?? 旋转数组的查找:二分查找"""
515 def findKey(target, array):
516 if not array:
517 return None
518 left, right = 0,len(array)-1
519 while left < right:
520 mid = (left + right)//2
521 if array[mid] == target:
522 return True
523 if array[mid] < array[right]: #右侧有序
524 if target > array[mid] and target <= array[right]:
525 left = mid + 1
526 else:
527 right = mid -1
528 else:
529 if target >= array[left] and target < array[mid]:
530 right = mid -1
531 else:
532 left = mid + 1
533 return False
534
535 """41 二维数组的查找"""
536 def findkey(target, array):
537 if not array:
538 return False
539 row ,col = 0, len(array[0])-1
540 while row <= len(array) and col>=0:
541 if array[row][col] == target:
542 return True
543 elif array[row][col] > target:
544 col -= 1
545 else:
546 row += 1
547 return False