云小杰

相对于绝对成功的汲汲渴求,越无杂质的奔赴,越是动人。

要一个黄昏, 满是风, 和正在落下的夕阳。如此, 足够我爱这破碎泥泞的人间。


Download the theme

找不同

389. 找不同

题目描述

给定两个字符串 st ,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。

请找出在 t 中被添加的字母。

示例 1:

输入s = "abcd", t = "abcde"
输出"e"
解释'e' 是那个被添加的字母

示例 2:

输入s = "", t = "y"
输出"y"

方法一:统计每个字母出现次数

​ 我看到这个题目的第一反应是用两个数组 ab 分别统计字符串 st 中每个字符出现的次数,然后遍历两个数组,数组b 比数组 a 多一个的便是多出来的字母;

class Solution {
    public char findTheDifference(String s, String t) {
        int[] a = new int[26];
        int[] b = new int[26];
        for (int i = 0; i < s.length(); i++) {
            a[s.charAt(i) - 'a']++;
            b[t.charAt(i) - 'a']++;
        }
        b[t.charAt(t.length()-1) - 'a']++;
        char ans = 0;
        for (int i = 0; i < 26; i++) {
            if (b[i] > a[i]) {
                ans = (char) (i + 'a');
            }
        }
        return ans;
    }
}

不过官方解答中的减法确实是比我的要好。空间复杂度要少。具体如下:

  • 首先遍历字符串 s,对其中的每个字符都将计数值加 1
  • 然后遍历字符串 t,对其中的每个字符都将计数值减 1
  • 当发现某个字符计数值为负数时,说明该字符在字符串 t 中出现的次数大于在字符串 s 中出现的次数,因此该字符为被添加的字符。
class Solution {
    public char findTheDifference(String s, String t) {
        int[] cnt = new int[26];
        for (int i = 0; i < s.length(); ++i) {
            char ch = s.charAt(i);
            cnt[ch - 'a']++;
        }
        for (int i = 0; i < t.length(); ++i) {
            char ch = t.charAt(i);
            cnt[ch - 'a']--;
            if (cnt[ch - 'a'] < 0) {
                return ch;
            }
        }
        return ' ';
    }
}

方法二:求和

将字符串 s 中每个字符的 ASCII 码的值求和,得到 ans1;对字符串 t 同样的方法得到 ans2 。两者的差值 ans2-ans1即代表了被添加的字符。

class Solution {
    public char findTheDifference(String s, String t) {
        char ans1 = 0, ans2 = 0;
        for (char c:s.toCharArray()) {
            ans1 += c;
        }
        for (char c:t.toCharArray()) {
            ans2 += c;
        }
        return (char) (ans2 -ans1;
    }
}

方法三:位运算

如果将两个字符串拼接成一个字符串,则问题转换成求字符串中出现奇数次的字符。类似于「136. 只出现一次的数字」,我们使用位运算的技巧解决本题。

class Solution {
    public char findTheDifference(String s, String t) {
        int ret = 0;
        for (int i = 0; i < s.length(); ++i) {
            ret ^= s.charAt(i);
        }
        for (int i = 0; i < t.length(); ++i) {
            ret ^= t.charAt(i);
        }
        return (char) ret;
    }
}
最近的文章

搜索旋转排序数组

搜索旋转排序数组题目描述整数数组 nums 按升序排列,数组中的值 互不相同 。在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。给...…

继续阅读
更早的文章

仅仅反转字母

917. 仅仅反转字母题目描述给你一个字符串 s ,根据下述规则反转字符串: 所有非英文字母保留在原有位置。 所有英文字母(小写或大写)位置反转。返回反转后的 s 。示例 1:输入:s = "ab-cd"输出:"dc-ba"示例 2:输入:s = "a-bC-dEf-ghIj"输出:"j-Ih-gfE-dCba"示例 3:输入:s = "Test1ng-Leet=code-Q!"输出:"Qedo1ct-eeLg=ntse-T!"方法:双指针​ 整体而言,这个题目还是比较简单的,双指针...…

继续阅读