1.栈的压入、弹出序列
2.从上往下打印二叉树
3.二叉搜索树的后续遍历序列
4.二叉树中和为某一值的路径
5.复杂链表的复制
6.二叉搜索树与双向链表
7.字符串的排列
8.数组中出现次数超过一半的数字
9.最小的K个数
10.连续子数组的最大和
1.栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
思路:借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。
举例:
入栈1,2,3,4,5
出栈4,5,3,2,1
首先1入辅助栈,此时栈顶1≠4,继续入栈2
此时栈顶2≠4,继续入栈3
此时栈顶3≠4,继续入栈4
此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3
此时栈顶3≠5,继续入栈5
此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3
依次执行,最后辅助栈为空。如果不为空说明弹出序列不是该栈的弹出顺序。
public boolean IsPopOrder(int [] pushA,int [] popA) {
if(pushA.length==0||popA.length==0)
return false;
Stack<Integer> s=new Stack<Integer>();//辅助栈
int popIndex=0;//弹出序列的位置
for(int i=0;i<pushA.length;i++){
s.push(pushA[i]);
while(!s.empty()&&s.peek()==popA[popIndex]){
s.pop();
popIndex++;
}
}
return s.empty();
}
2.从上往下打印二叉树
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
可以通过队列实现,也可以通过arraylist模拟一个队列实现
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
ArrayList<Integer> list=new ArrayList<>();
ArrayList<TreeNode> queue=new ArrayList<>();
if(root==null)
return list;
queue.add(root);
while(queue.size()!=0){
TreeNode temp=queue.remove(0);
if(temp.left!=null)
queue.add(temp.left);
if(temp.right!=null)
queue.add(temp.right);
list.add(temp.val);
}
return list;
}
public ArrayList<Integer> PrintFromTopToBottom2(TreeNode root) {
ArrayList<Integer> list=new ArrayList<>();
if(root==null)
return list;
Queue<TreeNode> queue=new LinkedList<TreeNode>();
queue.offer(root);
while(!queue.isEmpty()){
TreeNode treeNode=queue.poll();
if(treeNode.left!=null)
queue.offer(treeNode.left);
if(treeNode.right!=null)
queue.offer(treeNode.right);
list.add(treeNode.val);
}
return list;
}