LeetCode刷题记196-Stack(栈)

6 篇文章 0 订阅

1047. 删除字符串中的所有相邻重复项

class Solution {
    public String removeDuplicates(String S) {
        int[] sta = new int[S.length()];
        int id = 0;
        for (int i = 0; i < S.length(); i ++) {
            boolean f = false;
            while (id != 0) {
                if (S.charAt(i) == S.charAt(sta[id - 1])) {
                    f = true;
                    id --;
                } else {
                    break;
                }
            }
            if (!f) sta[id ++] = i;
        }
        String ans = "";
        for (int i = 0; i < id; i ++) {
            ans += S.charAt(sta[i]);
        }
        return ans;
    }
}

改进一:
StringBuilder效率远高于String

class Solution {
    public String removeDuplicates(String S) {
        char[] s = S.toCharArray();
        int[] sta = new int[S.length()];
        int id = 0;
        for (int i = 0; i < S.length(); i ++) {
            if (id != 0 && s[i] == s[sta[id - 1]]) {
                id --;
            } else {
                sta[id ++] = i;
            }
        }
        StringBuilder ans = new StringBuilder("");
        for (int i = 0; i < id; i ++) {
            ans.append(s[sta[i]]);
        }
        return ans.toString();
    }
}

改进二:
更省空间

class Solution {
    public String removeDuplicates(String S) {
        char[] s = S.toCharArray();
        int id = 0;
        for (int i = 0; i < S.length(); i ++) {
            if (id != 0 && s[i] == s[id - 1]) {
                id --;
            } else {
                s[id ++] = s[i];
            }
        }
        return String.valueOf(s, 0, id);
    }
}

880. 索引处的解码字符串
解法一:没有用Stack

class Solution {
    public String decodeAtIndex(String S, int K) {
        List<Character>[] words = new ArrayList[100];
        int[] num = new int[100];
        
        int id = 0;
        words[id] = new ArrayList<Character>();
        for (int i = 0; i < S.length(); i ++) {
            if (Character.isDigit(S.charAt(i))) {
                num[id] = S.charAt(i) - '0';
                words[++ id] = new ArrayList<Character>();
            } else {
                words[id].add(S.charAt(i));
            }
        }
        if (!Character.isDigit(S.charAt(S.length() - 1))) {
            num[id ++] = 1;
        }
        long[] sum = new long[id];
        sum[0] = (long)words[0].size() * (long)num[0];
        if (sum[0] >= K) {
            K %= words[0].size();
            if (K == 0) return "" + words[0].get(words[0].size() - 1);
            return "" + words[0].get(K - 1);
        }
        for (int i = 1; i < id; i ++) {
            sum[i] = (sum[i - 1] + words[i].size()) * num[i];
            if (sum[i] >= K) {
                while (i > 0) {
                    K %= (sum[i - 1] + words[i].size());
                    if (K == 0) {
                        while (words[i].size() == 0) {
                            i --;
                        }
                        return "" + words[i].get(words[i].size() - 1);
                    }
                    if (K > sum[i - 1]) {
                        K -= sum[i - 1];
                        while (words[i].size() == 0) {
                            i --;
                        }
                        return "" + words[i].get(K - 1);
                    } else {
                        i --;
                    }
                }
                if (i == 0) {
                    K %= words[0].size();
                    if (K == 0) return "" + words[0].get(words[0].size() - 1);
                    return "" + words[0].get(K - 1);
                }
            }
        }

        return "";
    }
}

解法二:想不明白用栈会这么样简便,算了。。。
895. 最大频率栈

class FreqStack {
    Map<Integer, Integer> map;  // 记录num和其出现次数
    List<Integer> sta;  // 用作栈
    int[] maxNum = new int[10001];  // 重复的数次出现i次的有maxNum[i]个
    int curMaxNum;  // 当前最多重复次数

    public FreqStack() {
        // map = new TreeMap<Integer, Integer>();
        map = new HashMap<Integer, Integer>();
        sta = new ArrayList<Integer>();
        curMaxNum = 0;
    }
    
    public void push(int val) {
        sta.add(val);
        int pre = map.getOrDefault(val, 0);
        map.put(val, pre + 1);
        maxNum[pre] --;
        maxNum[pre + 1] ++;
        curMaxNum = Math.max(curMaxNum, pre + 1);
    }
    
    public int pop() {
        int ans, tmp;
        for (int i = sta.size() - 1; i >= 0; i --) {
            ans = sta.get(i);
            tmp = map.get(ans);
            if (tmp == curMaxNum) {
                sta.remove(i);
                map.put(ans, tmp - 1);
                maxNum[tmp - 1] ++;
                maxNum[curMaxNum] --;
                if (maxNum[curMaxNum] == 0) {
                    curMaxNum --;
                }
                return ans;
            }
        }
        return -1;
    }
}

/**
 * Your FreqStack object will be instantiated and called as such:
 * FreqStack obj = new FreqStack();
 * obj.push(val);
 * int param_2 = obj.pop();
 */

224. 基本计算器
我真是有够蠢的,做了无数遍的题目,还是要花很长时间再做。。。

class Solution {
    public int calculate(String s) {
        s = s.replaceAll(" ", "");
        Stack<Integer> num = new Stack<Integer>();
        Stack<Character> op = new Stack<Character>();
        char[] chs = s.toCharArray();
        int curNum = 0;
        for (int i = 0; i < s.length(); i ++) {
            if (chs[i] == '(' || chs[i] == '+' || chs[i] == '-') {
                op.push(chs[i]);
            } else if (chs[i] == ')') {
                boolean f = false;
                while (!op.isEmpty()) {
                    char opItem = op.peek();
                    if (opItem == '(') {
                        if (f) break;
                        opItem = op.pop();
                        f = true;
                        continue;
                    } else {
                        op.pop();
                    }
                    if (num.size() < 2) {
                        if (opItem == '-') {
                            int num1 = num.pop();
                            num.push(- num1);
                        }
                        break; 
                    }
                    int num1 = num.pop();
                    int num2 = num.pop();
                    if (opItem == '-') num.push(num2 - num1);
                    else num.push(num2 + num1);
                }
            } else {
                curNum = 0;
                while (i < s.length() && (Character.isDigit(chs[i]))) {
                    curNum = curNum * 10 + chs[i] - '0'; 
                    i ++;
                }
                if (!op.isEmpty()) {
                    char opItem = op.peek();
                    if (opItem == '(') {
                        num.push(curNum);
                    } else {
                        op.pop();
                        int numItem = 0;
                        if (!num.isEmpty()) numItem = num.pop();
                        if (opItem == '-') num.push(numItem - curNum);
                        else num.push(numItem + curNum);
                    }
                } else {
                    num.push(curNum);
                }
                i --;
            }
        }
        if (!num.isEmpty()) return num.pop();
        return 0;
    }
}

227. 基本计算器 II

class Solution {
    public int calculate(String s) {
        Stack<Character> op = new Stack<Character>();
        Stack<Integer> nums = new Stack<Integer>();

        s = s.replaceAll(" ", "");
        if (s.length() == 0) return 0;
        char[] chs = s.toCharArray();
        for (int i = 0; i < s.length(); i ++) {
            if (Character.isDigit(chs[i])) {
                int num = 0;
                while (i < s.length() && Character.isDigit(chs[i])) {
                    num = num * 10 + chs[i] - '0';
                    i ++;
                }
                if (!op.isEmpty()) {
                    char opItem = op.peek();
                    if (opItem == '/') {
                        op.pop();
                        num = nums.pop()/num;
                    } else if (opItem == '*') {
                        op.pop();
                        num = nums.pop() * num;
                    }
                }
                nums.push(num);
                i --;
            } else {
                op.push(chs[i]);
            }
        }
        int num1 = nums.pop();
        while (!nums.isEmpty()) {
            int num2 = nums.pop();
            char opItem = op.pop();
            if (!op.isEmpty()) {
                char opItem2 = op.pop();
                if (opItem2 == '-') {
                    num2 = -num2;
                }
                op.push('+');
            }
            if (opItem == '-') {
                num1 = num2 - num1;
            } else {
                num1 = num2 + num1;
            }
        }
        if (!op.isEmpty()) {
            char opItem = op.pop();
            if (opItem == '-') {
                num1 = - num1;
            }
        }
        return num1;
    }
}

331. 验证二叉树的前序序列化

class Solution { 
    class MyItem {
        private int key;
        private int value;

        public MyItem(int key, int value) {
            this.key = key;
            this.value = value;
        }
        public int getValue() {
            return value;
        }
        public int getKey() {
            return key;
        }
        public void setValue(int value) {
            this.value = value;
        }
    }
    int i;
    public int getNum(String preorder) {
        int num = 0;
        for (; i < preorder.length(); i ++) {
            if (preorder.charAt(i) == ',') {
                i ++;
                break;
            }
            num = num * 10 + preorder.charAt(i) - '0';
        }
        return num;
    } 
    public boolean isValidSerialization(String preorder) {
        if (preorder.length() == 1) {
            if (preorder.charAt(0) == '#') return true;
            else return false;
        }
        if (preorder.charAt(0) == '#') return false;
        Stack<MyItem> sta = new Stack<MyItem>();
        i = 0;
        sta.push(new MyItem(getNum(preorder), 0));
        while (!sta.isEmpty()) {
            if (i >= preorder.length()) break;
            if (sta.peek().getValue() == 1) {
                sta.pop();
            } else {
                sta.peek().setValue(1);
            }
            if (preorder.charAt(i) == '#') {
                i += 2;
            } else {
                sta.push(new MyItem(getNum(preorder), 0));
            }
        }
        if (!sta.isEmpty() || i < preorder.length()) return false;

        return true;
    }
}

面试题 16.26. 计算器

class Solution {
    public int[] getNum(String s, int i) {
        int num = 0;
        while (i < s.length() && Character.isDigit(s.charAt(i))) {
            num = num * 10 + s.charAt(i) - '0';
            i ++;
        }
        return new int[]{num, i};
    }
    public int calculate(String s) {
        if (s == null) return 0;
        s = s.replaceAll(" ", "");
        if (s.length() == 0) return 0;
        Stack<Integer> nums = new Stack<Integer>();
        Stack<Character> ops = new Stack<Character>();
        int i = 0;
        while(i < s.length()) {
            if (nums.isEmpty()) {
                int[] tmp = getNum(s, i);
                nums.push(tmp[0]);
            } else {
                char op = s.charAt(i);
                int[] tmp = getNum(s, ++ i);
                if (op == '*' || op == '/') {
                    int num1 = nums.pop();
                    if (op == '*') nums.push(tmp[0] * num1);
                    else nums.push(num1/ tmp[0]);
                } else {
                    ops.push(op);
                    nums.push(tmp[0]);
                }
            }
        }
        char[] _ops = new char[ops.size()];
        int id = ops.size() - 1;
        while (!ops.isEmpty()) {
            char op = ops.pop();
            _ops[id --] = op;
        }
        int[] _nums = new int[nums.size()];
        id = nums.size() - 1;
        while (!nums.isEmpty()) {
            int num = nums.pop();
            _nums[id --] = num;
        }
        
        int ans = _nums[0];
        for (int _i = 1; _i < _nums.length; _i ++) {
            if (_ops[_i - 1] == '-') ans = ans - _nums[_i];
            else ans = ans + _nums[_i];
        }
        return ans;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值