剑指offer(2)-第20-40道面试题

mac2025-04-11  4

面试21:调整数组顺序使奇数位于偶数前面

题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分

class Solution: def reOrderArray(self, array): return sorted(array,key=lambda c:c%2,reverse=True) so=Solution() so.reOrderArray([1,2,3,4,5,6,7,8]) [1, 3, 5, 7, 2, 4, 6, 8]

采用两指针分别从首尾出发,当头指针遇到一个偶数,并且尾指针遇到一个奇数时,交换两指针的数字,直到两指针相遇。时间复杂度为 O(n),(类似于快排)

class Solution: def reOrderArray(self, array): n = len(array) head = 0 tail = n - 1 while head < tail: while array[head] % 2 != 0: head += 1 while array[tail] % 2 == 0: tail -= 1 array[head], array[tail] = array[tail], array[head] head += 1 tail -= 1 so=Solution() array=[1,2,3,4,5,6,7,8] so.reOrderArray(array) array [1, 7, 3, 5, 4, 6, 2, 8]

面试22:链表中倒数第k个结点

题目:输入一个链表,输出该链表中倒数第k个结点。

class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: def FindKthToTail(self, head, k): # write code here if head == None or k <= 0: return None pAhead = head pBhead = None for i in range(k-1): if pAhead.next != None: pAhead = pAhead.next else: return None pBhead = head while pAhead.next != None: pAhead = pAhead.next pBhead = pBhead.next return pBhead llist1 = ListNode(1) pnode = llist1 for i in range(2, 11): pnode.next = ListNode(i) pnode = pnode.next so=Solution() so.FindKthToTail(llist1,3).val 8

面试23:链表中环的入口结点

题目:一个链表中包含环,请找出该链表的环的入口结点。

class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: def EntryNodeOfLoop(self, pHead): meetNode = self.MeetNode(pHead) if not meetNode: return None loop = 1 flag = meetNode while flag.next != meetNode: loop += 1 flag = flag.next fast = pHead for i in range(loop): fast = fast.next slow = pHead while fast != slow: fast = fast.next slow = slow.next return fast def MeetNode(self, head): if not head: return None slow = head.next if slow == None: return None fast = slow.next while fast: if slow == fast: return slow slow = slow.next fast = fast.next.next node1= ListNode(1) node2= ListNode(2) node3= ListNode(3) node4= ListNode(4) node5= ListNode(5) node1.next=node2 node2.next=node3 node3.next=node4 node4.next=node5 node5.next=node2 so=Solution() head=so.EntryNodeOfLoop(node1) print(head.val) 2

面试24:反转链表

题目:输入一个链表,输出反转后的链表。

class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: # 返回ListNode def ReverseList(self, pHead): # write code here pReversedHead = None pNode = pHead pPrev = None while pNode != None: pNext = pNode.next if pNext == None: pReversedHead = pNode pNode.next = pPrev pPrev = pNode pNode = pNext return pReversedHead llist1 = ListNode(1) pnode = llist1 for i in range(2, 11): pnode.next = ListNode(i) pnode = pnode.next so = Solution() head=so.ReverseList(llist1) while head: print(head.val) head=head.next 10 9 8 7 6 5 4 3 2 1

面试25:合并两个排序的链表

题目:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: # 返回合并后列表 def Merge(self, pHead1, pHead2): if pHead1 == None: return pHead2 if pHead2 == None: return pHead1 pMergeHead = None if pHead1.val < pHead2.val: pMergeHead = pHead1 pMergeHead.next = self.Merge(pHead1.next,pHead2) else: pMergeHead = pHead2 pMergeHead.next = self.Merge(pHead1,pHead2.next) return pMergeHead llist1 = ListNode(1) pnode1 = llist1 for i in range(2, 11): pnode1.next = ListNode(i) pnode1 = pnode1.next llist2 = ListNode(5) pnode2 = llist2 for i in range(6, 11): pnode2.next = ListNode(i) pnode2 = pnode2.next so=Solution() head=so.Merge(llist1,llist2) while head: print(head.val) head=head.next 1 2 3 4 5 5 6 6 7 7 8 8 9 9 10 10

面试26:树的子结构

题目:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def HasSubtree(self, pRoot1, pRoot2): result = False if pRoot1 != None and pRoot2 != None: if pRoot1.val == pRoot2.val: result = self.DoesTree1haveTree2(pRoot1,pRoot2) if not result: result = self.HasSubtree(pRoot1.left,pRoot2) if not result: result = self.HasSubtree(pRoot1.right,pRoot2) return result def DoesTree1haveTree2(self,pRoot1,pRoot2): if pRoot2 == None: return True if pRoot1 == None: return False if pRoot1.val != pRoot2.val: return False return self.DoesTree1haveTree2(pRoot1.left, pRoot2.left) and self.DoesTree1haveTree2(pRoot1.right, pRoot2.right) Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(7) Root.right.left = TreeNode(6) Root.right.right = TreeNode(8) so=Solution() so.HasSubtree(Root,Root.right) True

面试27:二叉树的镜像

题目:操作给定的二叉树,将其变换为源二叉树的镜像。

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: # 返回镜像树的根节点 def Mirror(self, root): if root == None: return if root.left == None and root.right == None: return root ptemp = root.left root.left = root.right root.right = ptemp self.Mirror(root.left) self.Mirror(root.right) # 按行打印二叉树 def Print(self, pRoot): if pRoot is None: return [] nodes, res = [pRoot], [] while nodes: curStack, nextStack = [], [] for node in nodes: curStack.append(node.val) if node.left: nextStack.append(node.left) if node.right: nextStack.append(node.right) res.append(curStack) nodes = nextStack return res Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(7) Root.right.left = TreeNode(6) Root.right.right = TreeNode(8) so=Solution() print(so.Print(Root)) so.Mirror(Root) so.Print(Root) [[5], [3, 7], [2, 4, 6, 8]] [[5], [7, 3], [8, 6, 4, 2]]

面试28:对称的二叉树

题目:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def isSymmetrical(self, pRoot): return self.selfIsSym(pRoot,pRoot) def selfIsSym(self,root1,root2): if root1 == root2 and root2 == None: return True if root1 == None or root2 == None: return False if root1.val != root2.val: return False return self.selfIsSym(root1.left, root2.right) and self.selfIsSym(root1.right,root2.left) Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(3) Root.right.left = TreeNode(4) Root.right.right = TreeNode(2) so=Solution() so.isSymmetrical(Root) True

面试29:顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

class Solution: # matrix类型为二维列表,需要返回列表 def printMatrix(self, matrix): if not matrix: return [] rows = len(matrix) columns = len(matrix[0]) start = 0 result = [] while rows > start * 2 and columns > start * 2: self.PrintMatrixInCircle(matrix, columns, rows, start,result) start += 1 return result def PrintMatrixInCircle(self, matrix, columns, rows,start,result): endX = columns - 1 - start endY = rows - 1 - start # 从左到右打印一行 for i in range(start, endX+1): #number = matrix[start][i] result.append(matrix[start][i]) # 从上到下打印一行 if start < endY: for i in range(start+1, endY+1): #number = matrix[i][endX] result.append(matrix[i][endX]) # 从右到左打印一行 if start < endX and start < endY: for i in range(endX-1, start-1, -1): #number = matrix[endY][i] result.append(matrix[endY][i]) # 从下到上打印一行 if start < endX and start < endY-1: for i in range(endY-1, start, -1): #number = matrix[i][start] result.append(matrix[i][start]) so=Solution() so.printMatrix([[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]) [1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10]

面试30:包含main函数的栈

题目:定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

class Solution: def __init__(self): self.stack = [] self.minStack = [] def push(self, node): # write code here self.stack.append(node) if self.minStack == [] or node < self.min(): self.minStack.append(node) else: temp = self.min() self.minStack.append(temp) def pop(self): # write code here if self.stack == None or self.minStack == None: return None self.minStack.pop() self.stack.pop() def top(self): # write code here return self.stack[-1] def min(self): # write code here return self.minStack[-1] so=Solution() so.push(5) so.min() 5 so.push(1) so.min() 1

面试31:栈的压入、弹出序列

题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列 {1, 2, 3, 4, 5} 是某栈的压入序列,序列 {4, 5, 3, 2, 1} 是该压栈序列对应的一个弹出序列,但 {4, 3, 5, 1, 2} 就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

class Solution: def IsPopOrder(self, pushV, popV): # write code here if pushV == [] or popV == []: return False stack = [] for i in pushV: stack.append(i) while len(stack) and stack[-1] == popV[0]: stack.pop() popV.pop(0) if len(stack): return False else: return True so=Solution() so.IsPopOrder([1,2,3,4,5],[4,3,5,1,2]) False so.IsPopOrder([1,2,3,4,5],[4,5,3,2,1]) True

面试32:从上往下打印二叉树

题目一:不分行从上到下打印二叉树

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: # 返回从上到下每个节点值列表,例:[1,2,3] def PrintFromTopToBottom(self, root): # write code here if root is None: return [] queue = [] result = [] queue.append(root) while len(queue) > 0: currentRoot = queue.pop(0) result.append(currentRoot.val) if currentRoot.left: queue.append(currentRoot.left) if currentRoot.right: queue.append(currentRoot.right) return result Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(7) Root.right.left = TreeNode(6) Root.right.right = TreeNode(8) so=Solution() so.PrintFromTopToBottom(Root) [5, 3, 7, 2, 4, 6, 8]

题目二:分行上到下打印二叉树

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def Print(self, pRoot): # write code here if pRoot is None: return [] nodes,res = [pRoot],[] while nodes: curStack, nextStack = [],[] for node in nodes: curStack.append(node.val) if node.left: nextStack.append(node.left) if node.right: nextStack.append(node.right) res.append(curStack) nodes = nextStack return res Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(7) Root.right.left = TreeNode(6) Root.right.right = TreeNode(8) so=Solution() so.Print(Root) [[5], [3, 7], [2, 4, 6, 8]]

题目三:按之字形顺序打印二叉树

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def Print(self, pRoot): # write code here if not pRoot: return [] result,nodes = [],[pRoot] right = True while nodes: curStack, nextStack = [],[] if right: for node in nodes: curStack.append(node.val) if node.left: nextStack.append(node.left) if node.right: nextStack.append(node.right) else: for node in nodes: curStack.append(node.val) if node.right: nextStack.append(node.right) if node.left: nextStack.append(node.left) nextStack.reverse() right = not right result.append(curStack) nodes = nextStack return result Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(7) Root.right.left = TreeNode(6) Root.right.right = TreeNode(8) so=Solution() so.Print(Root) [[5], [7, 3], [2, 4, 6, 8]]

面试33:二叉搜索树的后序遍历序列

题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。

class Solution: def VerifySquenceOfBST(self, sequence): # write code here if sequence == []: return False length = len(sequence) root = sequence[-1] for i in range(length): if sequence[i] > root: break for j in range(i, length): if sequence[j] < root: return False left = True if i > 0: left = self.VerifySquenceOfBST(sequence[:i]) right = True if j < length - 1: right = self.VerifySquenceOfBST(sequence[i:length-1]) return left and right so=Solution() so.VerifySquenceOfBST([5,7,6,9,11,10,8]) True

面试34:二叉树中和为某一值的路径

题目:输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: # 返回二维列表,内部每个列表表示找到的路径 def FindPath(self, root, expectNumber): # write code here if not root or root.val > expectNumber: return [] if not root.left and not root.right and root.val == expectNumber: return [[root.val]] else: expectNumber -= root.val left = self.FindPath(root.left,expectNumber) right = self.FindPath(root.right,expectNumber) result = [[root.val]+i for i in left] for i in right: result.append([root.val]+i) return sorted(result, key=lambda x:-len(x)) Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(7) Root.right.left = TreeNode(6) Root.right.right = TreeNode(8) so=Solution() so.FindPath(Root,10) [[5, 3, 2]]

面试35:复杂链表的复制

题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

class RandomListNode: def __init__(self, x): self.label = x self.next = None self.random = None class Solution: # 返回 RandomListNode def Clone(self, pHead): # write code here if not pHead: return None pNode = pHead while pNode: pClone = RandomListNode(pNode.label) pClone.next = pNode.next pNode.next = pClone pNode = pClone.next pNode = pHead while pNode: pClone = pNode.next if pNode.random != None: pClone.random = pNode.random.next pNode = pClone.next pNode = pHead pCloneHead = pCloneNode = pNode.next pNode.next = pCloneHead.next pNode = pNode.next while pNode: pCloneNode.next = pNode.next pCloneNode = pCloneNode.next pNode.next = pCloneNode.next pNode = pNode.next return pCloneHead

面试题36:二叉搜索树与双向链表

题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def Convert(self, pRootOfTree): if not pRootOfTree: return None if not pRootOfTree.left and not pRootOfTree.right: return pRootOfTree self.Convert(pRootOfTree.left) left = pRootOfTree.left if left: while left.right: left = left.right pRootOfTree.left = left left.right = pRootOfTree self.Convert(pRootOfTree.right) right = pRootOfTree.right if right: while right.left: right = right.left pRootOfTree.right = right right.left = pRootOfTree while pRootOfTree.left: pRootOfTree = pRootOfTree.left return pRootOfTree Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(7) Root.right.left = TreeNode(6) Root.right.right = TreeNode(8) so=Solution() head=so.Convert(Root) while head: print(head.val) head=head.right 2 3 4 5 6 7 8

面试题37:序列化二叉树

题目:请实现两个函数,分别用来序列化和反序列化二叉树。

序列化二叉树:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串。需要注意的是,序列化二叉树的过程中,如果遇到空节点,需要以某种符号(这里用#)表示。以下图二叉树为例,序列化二叉树时,需要将空节点也存入字符串中。

反序列化二叉树:根据某种遍历顺序得到的序列化字符串,重构二叉树。具体思路是按前序遍历“根左右”的顺序,根节点位于其左右子节点的前面,即非空(#)的第一个节点是某子树的根节点,左右子节点在该根节点后,以空节点#为分隔符。

class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None class Solution: def __init__(self): self.flag = -1 def Serialize(self, root): if not root: return '#,' return str(root.val)+','+self.Serialize(root.left)+self.Serialize(root.right) def Deserialize(self, s): # write code here self.flag += 1 l = s.split(',') if self.flag >= len(s): return None root = None if l[self.flag] != '#': root = TreeNode(int(l[self.flag])) root.left = self.Deserialize(s) root.right = self.Deserialize(s) return root Root = TreeNode(5) Root.left = TreeNode(3) Root.left.left = TreeNode(2) Root.left.right = TreeNode(4) Root.right = TreeNode(7) Root.right.left = TreeNode(6) Root.right.right = TreeNode(8) so=Solution() s=so.Serialize(Root) print(s) so.Deserialize(s).val 5,3,2,#,#,4,#,#,7,6,#,#,8,#,#, 5

面试题38:字符串的排列

题目:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

class Solution: def Permutation(self, ss): # write code here if not ss: return [] if len(ss) == 1: return list(ss) charList = list(ss) charList.sort() pStr = [] for i in range(0, len(charList)): if i > 0 and charList[i] == charList[i - 1]: continue temp = self.Permutation(''.join(charList[:i]) + ''.join(charList[i + 1:])) for j in temp: pStr.append(charList[i] + j) return pStr so=Solution() so.Permutation("abc") ['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

面试题39:数组中出现次数超过一半的数字

题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

class Solution: def MoreThanHalfNum_Solution(self, numbers): # write code here length = len(numbers) if not numbers: return 0 result = numbers[0] times = 1 for i in range(1, length): if times == 0: result = numbers[i] times = 1 elif numbers[i] == result: times += 1 else: times -= 1 if not self.CheckNoreThanHalf(numbers, length, result): return 0 return result def CheckNoreThanHalf(self, numbers, length, number): times = 0 for i in range(length): if numbers[i] == number: times += 1 if times * 2 <= length: return False return True so=Solution() so.MoreThanHalfNum_Solution([1,2,3,2,2,2,5,4,2]) 2

面试题40:最小的k个数

题目:输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。

class Solution: def GetLeastNumbers_Solution(self, tinput, k): # write code here if not tinput or k > len(tinput): return [] tinput = self.quick_sort(tinput) return tinput[:k] def quick_sort(self, lst): if not lst: return [] pivot = lst[0] left = self.quick_sort([x for x in lst[1:] if x < pivot]) right = self.quick_sort([x for x in lst[1:] if x >= pivot]) return left + [pivot] + right so=Solution() so.GetLeastNumbers_Solution([4,5,1,6,2,7,3,8],4) [1, 2, 3, 4]

剑指offer(3)-第41-68道面试题

最新回复(0)