【LeetCode】1544. 整理字符串(Java)

给你一个由大小写英文字母组成的字符串 s 。

一个整理好的字符串中,两个相邻字符 s[i] 和 s[i + 1] 不会同时满足下述条件:

  • 0 <= i <= s.length - 2
  • s[i] 是小写字符,但 s[i + 1] 是相同的大写字符;反之亦然 。

请你将字符串整理好,每次你都可以从字符串中选出满足上述条件的 两个相邻 字符并删除,直到字符串整理好为止。

请返回整理好的 字符串 。题目保证在给出的约束条件下,测试样例对应的答案是唯一的。

注意:空字符串也属于整理好的字符串,尽管其中没有任何字符。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/make-the-string-great
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法一

双指针,不过写的比较乱。

class Solution {
    public String makeGood(String s) {
        if (s.length() == 1) return s;

        //双指针
        char[] ch = s.toCharArray();
        int index = 0;  //当前比较的下标
        int next = 1;   //表示下个比较的位置下标

        while (index < ch.length - 1 && next < ch.length) {
            //如果是已经被删除的位置,直接跳过
            if (ch[index] == '*' || ch[next] == '*') {
                if (ch[index] == '*')   index++;
                if (ch[next] == '*')    next++;
                continue;
            }

            if (index == next) {
                next++;
                continue;
            }

            //比较是否互为大小写
            if (ch[index] + 32 == ch[next] || ch[index] - 32 == ch[next]) {
                //删除成功以后,需要比较拼接起来的两个字符是否互为大小写
                ch[index] = '*';
                ch[next] = '*';

                //next:要向前一位
                next++;
                //index往后退一位,如果为'*',继续后退,一直到0
                while (index > 0 && ch[index] == '*') index--;
                //如果一直到0都是*,没有字符,那么index移到next的位置,next再加1
                if (index == 0 && ch[index] == '*') {
                    index = next;
                    next++;
                }
                continue;
            }
            //如果不相同,都向前移一位
            index++;
            next++;
        }

        StringBuilder sb = new StringBuilder();
        for (char c : ch) {
            if (c != '*')   sb.append(c);
        }
        //如果删除后长度为0,返回""
        return sb.length() == 0 ? "" : sb.toString();
    }
}

在这里插入图片描述
这个错误的次数,老踩坑师了。

解法二

看上图的运行错误次数就知道,解法一做完后,感觉身体被掏空~,然后逛了一下题解区,发现可以用栈来做,因为之前没怎么使用栈,没想到用栈来做,然后就自己写了一下,思路更清晰了,不过就是性能稍微差了些,比不了解法一。

class Solution {
    public String makeGood(String s) {
        if (s.length() == 1) return s;

        //栈
        char[] ch = s.toCharArray();
        Stack<Character> stack = new Stack<>();

        int index = 0;
        while (index < ch.length) {
            //如果栈为空,放入当前字符,然后进入下次循环
            if (stack.empty()) {
                stack.push(ch[index]);
                index++;
                continue;
            }

            //取出栈顶字符
            char c = stack.pop();
            //判断是否互为大小写
            if (ch[index] + 32 == c || ch[index] - 32 == c) {
                //不操作,进入下个循环
                index++;
                continue;
            }

            //不是互为大小写,把两个字符都压入到栈中
            stack.push(c);
            stack.push(ch[index]);
            index++;
        }

        //如果比较完后,栈为空,返回""
        if (stack.empty())  return "";

        //把栈中的字符全部取出
        StringBuilder sb = new StringBuilder();
        while (!stack.empty()) {
            sb.append(stack.pop());
        }
        return sb.reverse().toString();
    }
}

在这里插入图片描述
虽然用栈效率稍微差了些,不过省去了一些不必要的判断,代码看起来也更加清晰。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值