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

剑指Offer 1-41 代码(python实现)

  今天主要写了一下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

 

posted @ 2019-07-17 21:21  WSX_1994  阅读(358)  评论(0编辑  收藏  举报