栈和二叉树篇
前言
本次算法入门训练主要训练以下二个内容:
- 以特殊数据结构为载体的算法结构,比如:数组、链表、栈、二叉树等
- 以考察常见算法思想基础的算法题,比如:动态规划、贪心、回溯等
- 基于某种场景包装下的1和2
提示:以下是本篇文章正文内容
内容
第一题:删除链表中重复的结点
解题思路:这题主要要处理三种情况,第一可能没有重复节点,第二可能全部都是重复节点,第三可能只有部分重复节点这个还分为重复节点的区域在中间位置和直接到最后一个节点。
OJ链接:第一题
public class Solution {
public ListNode deleteDuplication(ListNode pHead) {
if(pHead == null){
return pHead;
}
//创建一个虚拟头节点是为了处理链表所有节点都是重复节点
ListNode head = new ListNode(-1);
head.next = pHead;
ListNode prev = head;
ListNode last = prev.next;
while(last != null){
//没有重复节点
while(last.next != null && last.val != last.next.val){
prev = prev.next;
last = last.next;
}
//有重复节点且解决重复节点就是尾节点的情况
while(last.next != null && last.val == last.next.val){
last = last.next;
}
//说明有重复节点
if(prev.next != last){
prev.next = last.next;
}
//last复原
last = last.next;
}
return head.next;
}
}
第二题:最小栈
解题思路:这题非常简单,只要想到要用辅助栈就很好解决了,看注释就能看懂。
OJ链接:第二题
import java.util.Stack;
public class Solution {
//一个数据栈,一个辅助栈
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
public void push(int node) {
s1.push(node);
//第一次插入辅助栈
if(s2.isEmpty()){
s2.push(node);
}else{
//和辅助栈栈顶元素比较,小与等于则插入
if(s2.peek() >= node){
s2.push(node);
}
}
}
public void pop() {
int tmp = s1.pop();
//删除时要比较一下是否和辅助栈的栈顶元素相同
if(tmp == s2.peek()){
s2.pop();
}
}
public int top() {
return s1.peek();
}
public int min() {
return s2.peek();
}
}
第三题:栈的压入、弹出序列
解题思路:这题的思路可能没那么好想,但是如果理解了代码实现起来就很简单,主要是理解栈的特性先进后出,即咱们要弹出的元素一定要是栈顶元素。
OJ链接:第三题
import java.util.*;
public class Solution {
public boolean IsPopOrder(int [] pushA, int [] popA) {
if (pushA == null || popA == null) {
return false;
}
//借助辅助栈完成
Stack<Integer> s = new Stack<>();
int i = 0;
int j = 0;
for (; i < pushA.length; i++) {
//如果栈顶元素的值不等于出栈序列且栈为空则一直压栈
s.push(pushA[i]);
//如果栈顶元素的值和出栈序列相同,且栈不为空则一直出栈
while (!s.isEmpty() && s.peek() == popA[j]) {
s.pop();
j++;
}
}
//如果栈为空说明,符合,不为空说明不符合
if (s.isEmpty()) {
return true;
}
return false;
}
}
第四题:二叉树的层序遍历
解题思路:这题也很简单但是要练的很熟,因为面试可能常考。大家画个图很好理解注释。
OJ链接:第四题
public class Solution {
public ArrayList<Integer> PrintFromTopToBottom(TreeNode root) {
//二叉树的层序遍历
//用一个队列辅助完成
//1.直接插入头节点
//2.队列抛出节点的同时把该节点的左右子树入队
ArrayList<Integer> ret = new ArrayList<>();
Queue<TreeNode> que = new LinkedList<>();
if(root == null){
return ret;
}
que.offer(root);
//如果队列为空就说明没有节点了
while(!que.isEmpty()){
TreeNode tmp = que.poll();
ret.add(tmp.val);
//如果该节点的左子树存在则入队
if(tmp.left != null){
que.offer(tmp.left);
}
//如果该节点的右子树存在则入队
if(tmp.right != null){
que.offer(tmp.right);
}
}
return ret;
}
}
总结
以上就是今天训练的内容,第一题呢就相当于对昨天链表题的一个复习,其余呢主要训练了大家对于栈的理解,以及辅助栈和辅助队列的使用,辅助栈是某些题型的一种很好的解法要多多理解和练习才行。