剑指offer(jz21--jz30)

jz21 栈的压入弹出序列

描述

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

思路分析

创建一个栈,进行进栈操作,同时进行出栈的判断,最后判断栈里是否还有元素,以此判断是否是出栈顺序。判断条件就是栈是否为空。
代码如下:

def solution(pushv,popv):
	stack=[]
	for i in range(len(pushv)):
		stack.append(pushv[i])
		while stack and stack[-1]==popv[0]:
			stack.pop()
			popv.pop(v)
	if stack:
		return False
	else:
		return True

jz22 从上到下打印二叉树

描述

从上往下打印出二叉树的每个节点,同层节点从左至右打印。

思路

层级输出二叉树的节点值,利用队列的先进先出的特性。

代码如下:

def jz22(root):
	queue=[]
	number=[]
	if not root:
		return []
	queue.append(root)
	while queue:
		s=queue.pop(0)
		number.append(s.val)
		if s.left:
			queue.append(s.left)
		if s.right:
			queue.append(s.right)
	return number

jz23 二叉搜索树的后序遍历序列

描述

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。(ps:我们约定空树不是二叉搜素树)

思路

判断是否是后序遍历,首先找出最后一个根节点。然后判断是否左边的节点值是否是一部分连续的比根节点小,一部分比根节点大。然后迭代输出。
代码如下:

def jz23(li):
	if li==[]:
		return False
	root=li[-1]
	for i in range(len(li)):
		if li[i]>root:
			break
	for j in range(i,len(li)):
		if li[j]<root:
			return False
	left=True
	if i>0:
		left=jz23(li[0:i])
	right=True
	if i<len(li)-1:
		right=jz(li[i:-1])
	return left and right

jz24 二叉树中和为某一值的路径

描述

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

思路

设置一条路径的值,还有一个记录可行路径的列表,先是寻找到判断条件,进行迭代。

代码如下:

class Solution:
	def __init__(self):
		self.onepath=[]
		self.patharray=[]
	def findpath(self,root,number):
		if root is None:
			return self.patharray
		self.onepath.append(root.val)
		number-=root.val
		if number==0 and not root.left and root.right:
			self.patharray.append(self.onepath[:])
		elif number>0:
			self.findpath(root.left,number)
			self.findpath(root.right,number)
		self.onepath.pop()
		return self.patharray

jz25 复杂链表的复制

描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。
在这里插入图片描述
示例:
输入:{1,2,3,4,5,3,5,#,2,#}
输出:{1,2,3,4,5,3,5,#,2,#}
解析:我们将链表分为两段,前半部分{1,2,3,4,5}为ListNode,后半部分{3,5,#,2,#}是随机指针域表示。
以上示例前半部分可以表示链表为的ListNode:1->2->3->4->5
后半部分,3,5,#,2,#分别的表示为
1的位置指向3,2的位置指向5,3的位置指向null,4的位置指向2,5的位置指向null

在这里插入图片描述

思路

链表分为两部分,一部分是单向链表,一部分是无序链表。
单向链表是容易复制的,而无序链表需要做一个字典辅助添加,因为单向链表复制后,两个链表就没有关系。

代码如下:

def jz25(head):
	nhead=Node(0)
	npre=nhead
	pre=head
	dic={}
	while pre:
		npre.next=Node(pre.val)
		dic[pre.val]=npre.next
		npre=npre.next
		pre=pre.next
	while head:
		if head.random:
			dic[head.val].random=dict[head.random.val]
	return nhead.next

jz26 二叉搜索树

描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示
在这里插入图片描述

注意:
1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构
4.你不用输出或者处理,示例中输出里面的英文,比如"From left to right are:"这样的,程序会根据你的返回值自动打印输出

示例:
输入: {10,6,14,4,8,12,16}
输出:From left to right are:4,6,8,10,12,14,16;From right to left are:16,14,12,10,8,6,4;
解析:
输入就是一棵二叉树,如上图,输出的时候会将这个双向链表从左到右输出,以及
从右到左输出,确保答案的正确

思路

对二叉搜索树进行中序遍历,并输出到列表中,并增加双向指针。

代码如下:

class Solution:
	def __init__(self):
		self.li=[]
	def jz26(self,root):
		self.pre(root)
		for i in range(len(li)-1):
			self.li[i].right=self.li[i+1]
			self.li[i+1].left=self.li[i]
		return self.li[0]
	def pre(self,root):
		if root:
			self.pre(root.left)
			self.li.append(root)
			self.pre(root.right)

jz28 数组中出现次数超过一半的数字

描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。你可以假设数组是非空的,并且给定的数组总是存在多数元素。1<=数组长度<=50000

思路

可以创建一个字典,每次遍历进行添加操作和判断操作。

代码如下:

def jz28(numbers):
	if len(numbers)<2:
		return numbers[0]
	length=len(numbers)
	dic={}
	for i in range(length):
		if numbers[i] in dic:
			dic[nuumbers[i]]+=1
			if dic[numbers[i]]>length//2:
				return numbers[i]
		else:
			dic[numbers[i]]=1 

jz29

描述

给定一个数组,找出其中最小的K个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4。如果K>数组的长度,那么返回一个空的数组

思路

排序,进行获取前k个值

代码如下:

class Solution:
    def GetLeastNumbers_Solution(self, tinput, k):
        # write code here
        tinput.sort()
        if len(tinput)<k:
            return None
        else:
            return tinput[0:k]

jz30

描述

输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).

思路

创建一个列表,保存每一个位置的最大值。

代码如下:

def jz30(array):
	maxli=[0 for _ in range(len(array))]
	maxli[0]=array[0]
	for i in range(1,len(array)):
		maxli[i]=max(max[i-1]+array[i],array[i])
	return max(maxli)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值