【Leecode笔记之java】第十一周下(11.19-11.22)字符串专题

【11.19】替换所有的问号

在这里插入图片描述分析:
***第一种方法:***可以建立一个空间为26的数组,里边存放26个不同的小写字母,遍历一遍字符串,将已存在于数组的字母设置为-1,到时候再遍历一次字符串,将问号换成字符数组里边value非-1的字母即可。
另外,其实普通的整型数组也可,就是再对应的时候稍微要转换一下,不过省掉了将字母存入数组的操作。

难点在于:如何让字符串种的字符以O(1)的时间复杂度对应到数组?
答:用ASCII码。小写a对应的ASCII码为97,z对应的是122,将其减去97则对应的就是字符数组下标
顺便复习一下,大写A对应的ASCII码为65,Z对应的是90。

***第二种方法:***只需要判断当前位置的?的取值不和前一个值以及后一个值相同即可。

//执行用时:2 ms, 在所有 Java 提交中击败了47.87% 的用户
//内存消耗:38.5 MB, 在所有 Java 提交中击败了41.83% 的用户
class Solution {
    public String modifyString(String s) {
        char[] chars = s.toCharArray();

        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '?') {
                //前面一个字符  如果当前是第0个的话 字符就为‘ ’
                char ahead = i == 0 ? ' ' : chars[i - 1];
                //后面一个字符  如果当前是最后一个的话 字符就为‘ ’
                char behind  = i == chars.length - 1 ? ' ' : chars[i + 1];
                //从a开始比较  如果等于前面或者后面的话 就+1
                char temp = 'a';
                while (temp == ahead || temp == behind ) {
                    temp++;
                }
                //找到目标字符后 做替换
                chars[i] = temp;
            }
        }
        return new String(chars);
    }
}


作者:JayceonDu
链接:https://leetcode-cn.com/problems/replace-all-s-to-avoid-consecutive-repeating-characters/solution/jian-dan-de-ji-xing-dai-ma-by-jayceondu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

【11.20】重复的子字符串

在这里插入图片描述
分析:这题标的easy我是万万没想到的…看题解的方法是用的一个数学证明
假如说给出的字符串是由某子字符串重复两次以上得到,那么就判定为true,否则为false

假如给定字符串为s,子字符串为x,重复次数为n。构造新字符串t = 2s(即两个s相加),由于s = nx,则t = 2nx。对t进行去头掐尾处理,这样的话,两处的子串被破坏掉,那么剩下的重复次数应该为2n-2,若t中包含s,那么由2n-2>=n,则n>=2。这样就满足了以上预设,判定为true。
(长话短说:假如t去头掐尾之后,s还是其子字符串,那么就为true)

难点:如何实现去头掐尾?
A1:从位置1开始查询,并希望查询结果不为位置n即可;

//执行用时:117 ms, 在所有 Java 提交中击败了14.87% 的用户
//内存消耗:38.9 MB, 在所有 Java 提交中击败了96.90% 的用户
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        return (s + s).indexOf(s, 1) != s.length();
    }
}
//执行用时:95 ms, 在所有 Java 提交中击败了48.71% 的用户
//内存消耗:39 MB, 在所有 Java 提交中击败了89.62% 的用户
class Solution{
	public boolean repeatedSubstringPattern(String s){
		String str = s+s;
		return str.substring(1,str.length()-1).contains(s);
	}
}

【11.21】上升下降字符串

在这里插入图片描述
分析:题意大概就是首先按照字符大小增序排列,然后降序,然后反复。
方法1:桶排序。长度为26的数组表示26个桶,每个桶里放一个字母,遍历一遍字符串,将字母放进对应的桶中,然后按照顺序遍历桶输出第一遍,然后逆序输出一遍,反复即可,(每输出一次,计数器-1)直到所有桶中的计数器为0.

//执行用时:4 ms, 在所有 Java 提交中击败了45.10% 的用户
//内存消耗:38.3 MB, 在所有 Java 提交中击败了92.24% 的用户
class Solution {
    int[] h = new int[26];

    public String sortString(String s) {
        for (int i = 0; i < s.length(); ++i) {
            ++h[s.charAt(i) - 'a'];
        }

        StringBuffer ret = new StringBuffer();

        while (true) {
            if (!haveChar()) {
                break;
            }
            for (int i = 0; i < 26; ++i) {
                appendChar(ret, i);
            }
            for (int i = 25; i >= 0; --i) {
                appendChar(ret, i);
            }
        }

        return ret.toString();
    }

    public void appendChar(StringBuffer ret, int p) {
        if (h[p] > 0) {
            --h[p];
            ret.append((char) (p + 'a'));
        }
    }

    public boolean haveChar() {
        for (int i = 0; i < 26; ++i) {
            if (h[i] != 0) {
                return true;
            }
        }
        return false;
    }
}

【11.22】字符串压缩
在这里插入图片描述分析:设置一个指针指向字母,相同则计数器+1,碰到不同的字母则将当前计数器的值放在结果字符串后,然后计数器清零。

class Solution {
    public String compressString(String S) {
        if (S.length() == 0) { // 空串处理
            return S;
        }
        StringBuffer ans = new StringBuffer();
        int cnt = 1;
        char ch = S.charAt(0);
        for (int i = 1; i < S.length(); ++i) {
            if (ch == S.charAt(i)) {
                cnt++;
            } else {
                ans.append(ch);
                ans.append(cnt);
                ch = S.charAt(i);
                cnt = 1;
            }
        }
        ans.append(ch);
        ans.append(cnt);
        return ans.length() >= S.length() ? S : ans.toString();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值