Day10|栈与队列

双指针总结

数组篇

数组
通过两个指针在一个for循环下完成两个for循环的工作。

字符串

原地反转字符串:字符串:这道题目,使用库函数一行代码搞定,使用前后两个指针,使用swap的方式将元素交换

原地替换空格:对于java而言,先使用一个StringBuilder将应该给String类型扩容的大小记录下来,加在原来的String类型的后面,使用toCharArray()的方式转换成char[],再使用两个指针,一个指向该string的末尾,一个指向该string的原字符串的末尾的位置,从后往前进行替换。

字符串:花式反转:反转字符串中单词的顺序,其中存在冗余的空格,首先将多余的空格删除,可以分成三部分,单词前的,单词末尾的,单词之间的。然后先将整个字符串翻转,再将每个单词翻转。复杂度为O(n)

链表:
反转链表:只需要改变链表的next指针的指向,直接将链表反转 ,而不用重新定义一个新的链表。也可以采用递归的方式,

ListNode list= reverseList(head.next);

 head.next.next=head;
 head.next=null;

list返回的头节点,而head.next为新节点的尾节点,将其next指向head,并且将head的next重置,避免形成环。

判断环形链表及其环起点
使用快慢指针,快指针两倍速前进,当快慢指针相遇时,必在环中,此时将快慢指针的任一个从头结点重新出发,重新相遇的节点即环入口。

N数之和
2数之和:使用哈希法,将已出现过的数存在map中,并且要记录下标
3数之和:先排序数组,使用双指针的方式,left指向i的下一位,right指向size-1,然后三个位置的和如果大于0,则right–,小于0则left++,如果等于0,那么left++,right–;同时双指针的移动放在while循环中进行,只要left<right,循环还是继续执行。需要注意此处需要剪枝操作,因为不需要重复的数据,当left++和right–原本的数据相同时,要跳过该位置

4数之和:和3数之和思想完全相同,对相应位置需要进行剪枝

栈与队列

Java中栈和队列的基本信息

学习文章:java中的队列介绍

队列

alt

Queue队列

Queue的6个方法分类:

压入元素(添加):add()、offer()
相同:未超出容量,从队尾压入元素,返回压入的那个元素。
区别:在超出容量时,add()方法会对抛出异常,offer()返回false

弹出元素(删除):remove()、poll()
相同:容量大于0的时候,删除并返回队头被删除的那个元素。
区别:在容量为0的时候,remove()会抛出异常,poll()返回false

获取队头元素(不删除):element()、peek()
相同:容量大于0的时候,都返回队头元素。但是不删除。
区别:容量为0的时候,element()会抛出异常,peek()返回null。

双端队列

deque 是“double ended queue(双端队列)”的缩写,通常读为“deck”。双端队列顾名思义就是队列的两个端口都能进出。

Deque的实现类是LinkedList,ArrayDeque,LinkedBlockingDeque,其中LinkedList是最常用的。值得注意的是,LinkedList也实现了List接口。

大多数Deque既可以是有容量限制也可以是无固定容量限制。

阻塞队列

阻塞队列是一个支持两个附加操作的队列,即在队列为满时,存储元素的线程会等待队列可用,当队列为空时,获取元素的线程会等待队列为非空。

阻塞队列接口有BlockingQueue和BlockingDeque两个,其中后者是双向队列。

题目

用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:

你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

class MyQueue {

    Stack<Integer> inStack;
    Stack<Integer> outStack;
    public MyQueue() {
        inStack=new Stack<>();
        outStack=new Stack<>();
    }

    public void push(int x) {
        inStack.push(x);

    }

    public int pop() {
        //如果出栈是空的,那么将inStack的数据全部导入
        if(outStack.isEmpty()){
            while(!inStack.isEmpty()){
              
                int num=inStack.pop();
                outStack.push(num);
            }
           
        }
        return outStack.pop();
    }

    public int peek() {
        if(outStack.isEmpty()){
            while(!inStack.isEmpty()){

                int num=inStack.pop();
                outStack.push(num);
            }

        }
        return outStack.peek();
    }

    public boolean empty() {
        if(inStack.isEmpty()&& outStack.isEmpty()){
            return true;
            
        }else{
            return false;
        }
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

用对列模拟栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

class MyStack {
    private Deque<Integer> deque;
    public MyStack() {
        deque=new ArrayDeque<>();
    }

    public void push(int x) {
       deque.addLast(x);
    }

    public int pop() {
        return deque.pollLast();
    }

    public int top() {
        return deque.peekLast();
    }

    public boolean empty() {
        return deque.isEmpty();
    }
}
/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值