Java栈常用操作及相关leetcode算法题

先进后出,后进先出。只有一个口。
例子:浏览器的页面前进后退操作。
判断数据结构的好坏要对比四个操作

1、访问Access

时间复杂度是O(1),只能访问栈顶的元素。

2、搜索Search

时间复杂度是O(N)。需要遍历才能找到对应的元素。

3、插入Insert

时间复杂度是O(1)。只能在栈顶插入元素。

4、删除Delete

时间复杂度为O(1)。只能在栈顶删除元素。

Java栈常用操作

1、创建栈

Stack<Integer> stack = new Stack<>();

2、添加元素

stack.push(1);
stack.push(2);
stack.push(3);
时间复杂度是O(1),只能在栈顶添加元素。

3、获取栈顶元素

int top = stack.peek();
时间复杂度是O(1)。

4、删除栈顶元素

int top = stack.pop();
时间复杂度是O(1)。

5、获取栈的长度

int length = stack.size();
时间复杂度为O(1)。创建栈时会定义一个变量来记录栈的长度,增删时会随之改变,获取长度即直接返回这个变量,不用遍历栈。

6、判断栈是否为空

boolean isEmpty = stack.isEmpty();

7、栈的遍历

while(!stack.isEmpty()) {
int top = stack.pop();
}

8、栈相关leetcode

No.20 有效的括号

思路:
如果字符串为空,直接返回true。
创建栈,遍历字符串的字符数组,如果是左括号就入栈;否则即右括号,先判断栈是否为空,是则说明栈内没有左括号可以与之匹配,直接返回false。栈不为空则判断是哪种类型的右括号,取出栈顶元素将其匹配,如果匹配不上,则返回false。
遍历结束后,判断栈是否为空,不为空则说明栈中还有剩余的左括号,没有右括号与之匹配,返回false。
最后返回true。

class Solution {
    public boolean isValid(String s) {
        if(s.length() == 0)
            return true;
        Stack<Character> stack = new Stack<>();
        for(char c : s.toCharArray()) {
            if(c == '(' || c == '[' || c == '{') {
                stack.push(c);
            } else {
                if(stack.isEmpty())
                    return false;
                if(c == ')') {
                    char top = stack.pop();
                    if(top != '(')
                        return false;
                }
                if(c == ']') {
                    char top = stack.pop();
                    if(top != '[')
                        return false;
                }
                if(c == '}') {
                    char top = stack.pop();
                    if(top != '{')
                        return false;
                }
            }
        }
        if(!stack.isEmpty())
            return false;
        return true;
    }
}
No.496 下一个更大的元素

思路一:使用两个栈,先将数组2的元素放进stack中,然后遍历数组1的元素,每轮遍历创建临时变量max记录比当前元素大的元素,初始化为-1,表示还没找到,将其加入result中。临时变量isFound表示是否已经到达了相同元素的位置,因为我们只关心元素之后大于它的元素,所以到达了相同元素的位置后就不用再继续遍历栈了。while判断stack不为空且isFound为false,遍历stack,将删除的元素放入栈temp中。如果栈顶元素大于当前元素,将栈顶元素赋值给max;如果栈顶元素等于当前元素,将isFound设置为true,则退出栈的遍历。栈遍历结束后,如果isFound为true,就将result中的位置i设置为max。然后将temp中的元素还给stack。

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        ArrayList<Integer> result = new ArrayList<>(); 
        Stack<Integer> stack = new Stack<>();
        Stack<Integer> temp = new Stack<>();
        for(int i = 0; i < nums2.length; i++) {
            stack.push(nums2[i]);
        }
        for(int i = 0; i < nums1.length; i++) {
            int max = -1;
            boolean isFound = false;
            result.add(-1);
            while(!stack.isEmpty() && !isFound) {
                int top = stack.pop();
                temp.push(top);
                if(top > nums1[i])
                    max = top;
                if(top == nums1[i]) {
                    isFound = true;
                }
            }
            if(isFound)
                result.set(i, max);
            while(!temp.isEmpty()) {
                int top = temp.pop();
                stack.push(top);
            }
        }
        return result.stream().mapToInt(k->k).toArray();
    }
}

思路二:不使用栈。遍历数组1,每轮遍历创建变量max,加入result,变量isFound,嵌套遍历数组2,数组2是反向遍历的,如果数组1的元素等于数组2的元素,将isFound设为true,表示已经遍历完了目标元素的后面所有元素;如果数组2的元素大于数组1的元素,将数组2的元素赋值给max,数组2每遍历完一轮,判断isFound是否为true,是则将result的位置i设置为max。

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        ArrayList<Integer> result = new ArrayList<>();
        if(nums1 == null || nums1.length == 0)
            return nums1;
        for(int i = 0; i < nums1.length; i++) {
            int max = -1;
            result.add(max);
            boolean isFound = false;
            for(int j = nums2.length - 1; j >= 0 && !isFound; j--) {
                if(nums2[j] == nums1[i]) {
                    isFound = true;
                }
                if(nums2[j] > nums1[i])
                    max = nums2[j];
            }
            if(isFound)
                result.set(i, max);
        }
        return result.stream().mapToInt(k->k).toArray();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值