leeetcode 随笔19

再更新。
这两天主要在做简单难度的题,等我大致把简单难度的题都过一遍,再去做中等难度的题目。

文章目录

8.15

66. 加一

难度简单

用之前类似字符串相加的方法做的。这样的话是用了额外空间,而且链表和数组的赋值替换比较费时间。

class Solution {
    public int[] plusOne(int[] digits) {
        if(digits.length == 0){
            return new int[]{1};
        }
        int carry = 1;
        int index = digits.length - 1;
        List<Integer> list = new ArrayList<>();
        while(index >= 0 || carry > 0){
            int val = index >= 0 ? digits[index] : 0;
            int sum = val + carry;
            list.add(sum % 10);
            carry = sum / 10;

            index--;
        }

        int[] ans = new int[list.size()];
        for(int i = 0;i < ans.length;i++){
            ans[i] = list.get(ans.length - i - 1);
        }
        return ans;
    }
}

然后写了一种原地修改的写法,不过原地修改的前提是数组长度不变,如果加一之后数组长度变长,那么就只能再重新开辟一个新的数组。

class Solution {
    public int[] plusOne(int[] digits) {
        if(digits.length == 0){
            return new int[]{1};
        }
        int carry = 1;
        int index = digits.length - 1;
        while(index >= 0){
            digits[index] += carry;
            if(digits[index] >= 10){
                carry = digits[index] / 10;
                digits[index] %= 10;
                index--; 
            }else{
                carry = 0;
                return digits;
            }
        }
        
        if(carry > 0){
            int[] ans = new int[digits.length + 1];
            ans[0] = carry;
            System.arraycopy(digits, 0, ans, 1, digits.length);
            return ans;
        }
        return null;//正常来说是无法到达的
    }
}

69. x 的平方根

难度简单

本来是直接调用了Math.sqrt()函数直接解决的。不过不能偷懒了,就改用了二分查找的算法来实现。

class Solution {
    public int mySqrt(int x) {
        int begin = 0;
        int end = x;
        int ans = 0;

        while(begin <= end){
            int mid = begin + (end - begin) / 2;
            if((long)mid * mid <= x){
                ans = mid;
                begin = mid + 1;
            }else{
                end = mid - 1;
            }
        }

        return ans;
    }
}

155. 最小栈

难度简单

也算是比较经典的题目了,用两个栈来实现

class MinStack {
    Stack<Integer> myStack;
    Stack<Integer> minStack;
    /** initialize your data structure here. */
    public MinStack() {
        myStack = new Stack<>();
        minStack = new Stack<>();
    }
    
    public void push(int x) {
        if(minStack.isEmpty() || minStack.peek() >= x){
            minStack.push(x);
        }else if(minStack.peek() <= x){
            minStack.push(minStack.peek());
        }
        myStack.push(x);
    }
    
    public void pop() {
        myStack.pop();
        minStack.pop();
    }
    
    public int top() {
        return myStack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 */

168. Excel表列名称

难度简单

实际上就是一个进制的转换,需要注意的是它是从1 - 26,而不是0 - 25.所以为了能够正常的表示,我们有一步特殊操作(c == 0)

class Solution {
    //实际上就是把十进制的数变为二十六进制
    public String convertToTitle(int n) {
        StringBuilder sb = new StringBuilder();
        while (n > 0) {
            int c = n % 26;
            if(c == 0){
                c = 26;
                n -= 1;//之后的n / 26 是可以整除的,但是按照列的转换规则,他应该取比他小的下一个整数,所以让n--
            }
            sb.insert(0, (char) ('A' + c - 1));
            n /= 26;
        }
        return sb.toString();
    }

}

165. 比较版本号

难度中等

主要思想就是先将字符串进行分割,之后再根据得到的字符串数组进行对比判断。

尤其需要注意的一点是String的分割时用的是"//.“而不是”."。这个问题很关键。

class Solution {
    public boolean isEqualsZero(int index, String[] v){
        for(int i = index;i < v.length;i++){
            if(Integer.parseInt(v[i]) != 0){
                return false;
            }
        }
        return true;
    }

    public int compareVersion(String version1, String version2) {
        String[] v1 = version1.split("\\.");
        String[] v2 = version2.split("\\.");

        int index1 = 0;
        int index2 = 0;
        
        while(index1 < v1.length || index2 < v2.length){
            if(index1 == v1.length){
                if(isEqualsZero(index2, v2)){
                    break;
                }
                return -1;
            }else if(index2 == v2.length){
                if(isEqualsZero(index1, v1)){
                    break;
                }
                return 1;
            }
            int val1 = Integer.parseInt(v1[index1]);
            int val2 = Integer.parseInt(v2[index2]);
            if(val1 > val2){
                return 1;
            }else if(val1 < val2){
                return -1;
            }

            index1++;
            index2++;
        }
        return 0;
    }
}

171. Excel表列序号

难度简单

二十六进制转变成十进制即可。

class Solution {
    public int titleToNumber(String s) {
        char[] arr = s.toCharArray();
        int ans = 0;
        int len = arr.length;
        for(int i = 0;i < len;i++){
            int num = arr[i] - 'A' + 1;
            ans += (int)Math.pow(26, len - i - 1) * num;
        }
        return ans;
    }
}

172. 阶乘后的零

难度简单

为了得到后面的0,我们可以注意到,阶乘如果后面会出现零,那么只可能是2 * 5的情况,所以我们只需要去计算其中2的个数和5的个数就行。但是再想一想,我们发现2的出现频率一定比5要高,所以我们实际上计算出5的个数就能得出阶乘后零的个数。

class Solution {
    //要出现0,那么就要计算其中的2的个数和5的个数(2的个数一定大于5的个数,所以实质上只需要去找到其中拥有的5的个数就可以了)
    public int trailingZeroes(int n) {
        int zeroCount = 0;
        for(int i = 5;i <= n;i += 5){
            int temp = i;
            while(temp % 5 == 0){//累加上5的个数
                zeroCount++;
                temp /= 5;
            }
        }
        return zeroCount;
    }
}

205. 同构字符串

难度简单

ascii码总共有128位,所以用128长度的数组来标识前一个字符出现的位置。首先需要把数组都初始化为-1,以免造成映射到第0位的错误。

class Solution {
    public boolean isIsomorphic(String s, String t) {
        if(s.length() != t.length()){
            return false;
        }
        int[] count1 = new int[128];
        int[] count2 = new int[128];
        Arrays.fill(count1, -1);
        Arrays.fill(count2, -1);
        for(int i = 0;i < s.length();i++){
            char a = s.charAt(i);
            char b = t.charAt(i);
            if(count1[a] == count2[b]){
                count1[a] = i;
                count2[b] = i;
            }else{
                return false;
            }
        }
        return true;
    }
}

219. 存在重复元素 II

难度简单

暴力求解

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        for(int i = 0;i < nums.length;i++){
            for(int j = i + 1;j <= i + k && j < nums.length;j++){
                if(nums[i] == nums[j]){
                    return true;
                }
            }
        }
        return false;
    }
}

还有就是借助一个set来辅助存取(有点像一个无序的窗口)。

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        Set<Integer> set = new HashSet<>();
        for(int i = 0;i < nums.length;i++){
            if(set.contains(nums[i])){
                return true;
            }
            set.add(nums[i]);
            if(set.size() > k){
                set.remove(nums[i - k]);
            }
        }
        return false;
    }
}

8.16

225. 用队列实现栈

难度简单

也算是比较经典的题目了,最开始把队列的性质想错了,所以做错了。

实际上我们只需要借助两个队列,交替元素位置,找到队列的最后一个元素就是弹出的值。

class MyStack {
    Queue<Integer> queue1;
    Queue<Integer> queue2;
    /** Initialize your data structure here. */
    public MyStack() {
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }
    
    /** Push element x onto stack. */
    public void push(int x) {
        while(!queue2.isEmpty()){
            queue1.offer(queue2.poll());
        }
        queue1.offer(x);
    }
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() {
        int val = -1;
        if(!queue1.isEmpty()){
            while(!queue1.isEmpty()){
                if(queue1.size() == 1){
                    val = queue1.poll();
                }else{
                    queue2.offer(queue1.poll());
                }
            }
        }else{
            while(!queue2.isEmpty()){
                if(queue2.size() == 1){
                    val = queue2.poll();
                }else{
                    queue1.offer(queue2.poll());
                }
            }
        }
        return val;
    }
    
    /** Get the top element. */
    public int top() {
        int val = -1;
        if(!queue1.isEmpty()){
            while(!queue1.isEmpty()){
                if(queue1.size() == 1){
                    val = queue1.peek();
                }
                queue2.offer(queue1.poll());
            }
        }else{
            while(!queue2.isEmpty()){
                if(queue2.size() == 1){
                    val = queue2.peek();
                }
                queue1.offer(queue2.poll());
            }
        }
        return val;
    }
    
    /** Returns whether the stack is empty. */
    public boolean empty() {
        return queue1.isEmpty() && queue2.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

733. 图像渲染

难度简单

就是一个简单的深度优先遍历,其中需要注意的点是oldColor和newColor相同的情况,这时可以直接退出。

class Solution {
    public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
        if(image.length == 0){
            return new int[0][];
        }
        
        dfs(image, sr, sc, image[sr][sc], newColor);
        return image;
    }


    public void dfs(int[][] image, int i, int j, int oldColor, int newColor){
        if(oldColor == newColor){
            return ;
        }
        if(i >= 0 && i < image.length && j >=0 && j < image[0].length && image[i][j] == oldColor){
            image[i][j] = newColor;

            dfs(image, i + 1, j, oldColor, newColor);
            dfs(image, i - 1, j, oldColor, newColor);
            dfs(image, i, j + 1, oldColor, newColor);
            dfs(image, i, j - 1, oldColor, newColor);
        }
    }
}

231. 2的幂

难度简单

比较简单的题越需要注意。这里输入的整数可能是非正数,这时可以直接返回false。

class Solution {
    public boolean isPowerOfTwo(int n) {
        if(n <= 0){
            return false;
        }
        while(n > 1){
            if(n % 2 != 0){
                return false;
            }
            n = n >> 1;
        }
        return true;
    }
}

232. 用栈实现队列

难度简单

这个题也是比较经典的题目

class MyQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;
    /** Initialize your data structure here. */
    public MyQueue() {
        stack1 = new Stack<>();
        stack2 = new Stack<>();
    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {
        while(!stack2.isEmpty()){
            stack1.push(stack2.pop());
        }
        stack1.push(x);
    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
        while(!stack1.isEmpty()){
            stack2.push(stack1.pop());
        }
        return stack2.pop();
    }
    
    /** Get the front element. */
    public int peek() {
        while(!stack1.isEmpty()){
            stack2.push(stack1.pop());
        }
        return stack2.peek();
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
        return stack1.isEmpty() && stack2.isEmpty();
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

235. 二叉搜索树的最近公共祖先

难度简单

之前做过类似的题目。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == q || root == p){
            return root;
        }
        TreeNode left = lowestCommonAncestor(root.left, p, q);
        TreeNode right = lowestCommonAncestor(root.right, p, q);
        if(left == null){
            return right;
        }else if(right == null){
            return left;
        }else{
            return root;
        }
    }
}

上面的做法是通用的解法,如果树是BST,那么我们就可以利用BST的性质来优化算法。

如果p、q节点的值都比root的值要小,则最近公共祖先一定在root的左子树上。如果都要更大,那么最近公共祖先一定在root的右子数上。不然的话root就是他们最近的公共祖先。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */

class Solution {
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root == null || root == q || root == p){
            return root;
        }
        int val = root.val;
        int val1 = p.val;
        int val2 = q.val;

        if(val > val1 && val > val2){
            return lowestCommonAncestor(root.left, p, q);
        }else if(val < val1 && val < val2){
            return lowestCommonAncestor(root.right, p, q);
        }else{
            return root;
        }
    }
}

242. 有效的字母异位词

难度简单

通用的解法是利用哈希表。如果使用哈希表的话,需要注意的一点是关于Integer的相等判断,如果字符串足够长,关于Integer的相等判断就不能利用来进行判断(因为Integer是一个引用对象,在值小于128时,内部的比较是利用int值来比较的。如果值大于等于128,那么比较的就是两者的引用是否相同)。

class Solution {
    public boolean isAnagram(String s, String t) {
        Map<Character, Integer> map1 = getCharMap(s);
        Map<Character, Integer> map2 = getCharMap(t);

        if(map1.size() != map2.size()){
            return false;
        }

        for(Map.Entry<Character, Integer> entry : map1.entrySet()){
            if(!map2.containsKey(entry.getKey()) || 
            !map2.get(entry.getKey()).equals(entry.getValue())){
                return false;
            }
        }

        return true;
    }


    public Map<Character, Integer> getCharMap(String str){
        Map<Character, Integer> map = new HashMap<>();
        for(char c : str.toCharArray()){
            if(map.containsKey(c)){
                map.put(c, map.get(c) + 1);
            }else{
                map.put(c, 1);
            }
        }
        return map;
    }
}

如果只包含ascii字符的话,可以将哈希表简化成一个长度128得到数组,分别遍历两个字符串,看数组最后是不是全为0即可。

257. 二叉树的所有路径

难度简单

深度优先遍历,利用一个list来辅助存储遍历到的值。当退出当前遍历时,把本次加入的值去掉。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> ans = new LinkedList<>();
        if(root == null){
            return ans;
        }
        dfs(root, ans, new LinkedList<String>());
        return ans;
    }

    public void dfs(TreeNode root, List<String> ans, List<String> path){
        path.add(String.valueOf(root.val));
        if(root.left == null && root.right == null){
            StringBuilder sb = new StringBuilder();
            for(String str : path){
                sb.append(str).append("->");
            }
            ans.add(sb.toString().substring(0, sb.length() - 2));
        }else{
            if(root.left != null){
                dfs(root.left, ans, path);
            }
            if(root.right != null){
                dfs(root.right, ans, path);
            }
        }
        path.remove(path.size() - 1);
    }
}

258. 各位相加

难度简单

一个简单的数字的各位处理。

class Solution {
    public int addDigits(int num) {
        while(num / 10 != 0){
            int temp = 0;
            while(num > 0){
                temp += num % 10;
                num /= 10;
            }
            num = temp;
        }
        return num;
    }
}

263. 丑数

难度简单

暴力解决。

class Solution {
    public boolean isUgly(int num) {
        if(num < 1){
            return false;
        }

        while(num > 5){
            if(num % 2 == 0){
                num /= 2;
            }else if(num % 3 == 0){
                num /= 3;
            }else if(num % 5 == 0){
                num /= 5;
            }else{
                return false;
            }
        }
        return true;
    }
}

264. 丑数 II

难度中等

借助了一个set来辅助判断是否是丑数,但是最后超时了。

超时的可能大概是因为我是按照顺序去找丑数,每个数都进行了判断,花费了太多时间。换种想法,根据之前的丑数计算出下一个丑数,这样就能跳过很多数字。

class Solution {
    public int nthUglyNumber(int n) {
        if(n < 1){
            return -1;
        }
        Set<Integer> set = new HashSet<>();

        for(int i = 1;i <= 5;i++){
            set.add(i);
            if(set.size() == n){
                return i;
            }
        }

        for(int i = 6;set.size() < n;i++){
            if((i % 2 == 0 && set.contains(i / 2)) || (i % 3 == 0 && set.contains(i / 3)) || (i % 5 == 0 && set.contains(i / 5))){
                set.add(i);
                if(set.size() == n){
                    return i;
                }
            }
        }
        return -1;
    }
}

其中需要注意的点是更新三个指针。只要满足要求就需要更新,而不是只更新满足条件的一个。不然会出现重复的数字。

class Solution {
    public int nthUglyNumber(int n) {
        if(n < 1){
            return -1;
        }
        
        int[] dp = new int[1690];
        int i2 = 0;
        int i3 = 0;
        int i5 = 0;
        dp[0] = 1;
        int ugly;
        for(int i = 1;i < 1690;i++){
            ugly = Math.min(Math.min(dp[i2] * 2, dp[i3] * 3), dp[i5] * 5);

            dp[i] = ugly;
            if(ugly == dp[i2] * 2){
                i2++;
            }

            if(ugly == dp[i3] * 3){
                i3++;
            }
            
            if(ugly == dp[i5] * 5){
                i5++;
            }
        }

        return dp[n - 1];
    }
}

290. 单词规律

难度简单

说实话,这个题应该没那么难,但是自己实现的时候还是有点困难。

其中需要注意的点是pattern和str切分后的数组长度不一致,和同一个字符串映射到了不同的字符上。只要注意这两个地方,那问题应该不大。

class Solution {
    public boolean wordPattern(String pattern, String str) {
        String[] arr = str.split(" ");
        if(arr.length != pattern.length()){
            return false;
        }
        int[] count = new int[26];
        Arrays.fill(count, -1);

        Map<String, Character> map = new HashMap<>();
        int i = 0;
        for(char c : pattern.toCharArray()){
            int index = count[c - 'a'];
            if(index != -1){
                if(!arr[index].equals(arr[i]) || !map.get(arr[index]).equals(c)){
                    return false;
                }
            }
            if(map.containsKey(arr[i]) && !map.get(arr[i]).equals(c)){
                return false;
            }
            
            map.put(arr[i], c);
            count[c - 'a'] = i;
            i++;   
        }
        return true;
    }
}

292. Nim 游戏

难度简单

列举了几个数字,从1 - 14.发现当n是4的倍数时一定返回false。所以大胆推测n = 4的倍数时一定会输。其余情况都会赢。

class Solution {
    public boolean canWinNim(int n) {
        if(n <= 3){
            return true;
        }
        return n % 4 != 0;
    }    
}

299. 猜数字游戏

难度简单

比较简单的一题。利用两个count数组来确定公牛和奶牛的数量即可。

class Solution {
    public String getHint(String secret, String guess) {
        char[] arr1 = secret.toCharArray();
        char[] arr2 = guess.toCharArray();

        int[] count1 = new int[10];
        int[] count2 = new int[10];

        for(char c : arr1){
            count1[c - '0']++;
        }

        for(char c : arr2){
            count2[c - '0']++;
        }
        int A = 0;
        int B = 0;

        for(int i = 0;i < arr1.length;i++){
            if(arr1[i] == arr2[i]){
                count1[arr1[i] - '0']--;
                count2[arr1[i] - '0']--;
                A++;
            }
        }

        for(int i = 0;i < 10;i++){
            B += Math.min(count1[i], count2[i]);
        }

        return A + "A" + B + "B";
    }
}

326. 3的幂

难度简单

普通的方法是这样做的。

class Solution {
    public boolean isPowerOfThree(int n) {
        if(n < 1 || n == 2){
            return false;
        }
        while(n >= 3){
            if(n % 3 != 0){
                return false;
            }
            n /= 3;
        }

        return n == 1;
    }
}

342. 4的幂

难度简单

和上一题一样

class Solution {
    public boolean isPowerOfFour(int n) {
        if(n < 4 && n != 1){
            return false;
        }
        while(n >= 4){
            if(n % 4 != 0){
                return false;
            }
            n /= 4;
        }
        return n == 1;
    }
}

345. 反转字符串中的元音字母

难度简单

最开始用了顺序遍历,发现超时了。

class Solution {
    public String reverseVowels(String s) {
        if(s == null){
            return "";
        }
        // a e i o u
        StringBuilder sb = new StringBuilder();

        Set<Character> set = new HashSet<>();
        set.add('a');
        set.add('e');
        set.add('i');
        set.add('o');
        set.add('u');
        set.add('A');
        set.add('E');
        set.add('I');
        set.add('O');
        set.add('U');


        List<Integer> list = new ArrayList<>();

        char[] arr = s.toCharArray();
        for(int i = 0;i < arr.length;i++){
            if(set.contains(arr[i])){
                list.add(i);
                sb.append(String.valueOf(arr[i]));
            }
        }

        String str = sb.reverse().toString();
        int index = 0;
        for(int i = 0;i < arr.length;i++){
            if(list.contains(i)){
                arr[i] = str.charAt(index++);
            }
        }

        return String.valueOf(arr);
    }
}

看了眼提示,发现可以用双指针来做。这题的双指针也比较简单。

class Solution {
    public String reverseVowels(String s) {
        if(s == null){
            return "";
        }

        Set<Character> set = new HashSet<>();
        set.add('a');
        set.add('e');
        set.add('i');
        set.add('o');
        set.add('u');
        set.add('A');
        set.add('E');
        set.add('I');
        set.add('O');
        set.add('U');

        char[] arr = s.toCharArray();
        int begin = 0;
        int end = arr.length - 1;

        while(begin < end){
            while(begin < end && !set.contains(arr[begin])){
                begin++;
            }
            while(begin < end && !set.contains(arr[end])){
                end--;
            }
            if(begin == end){
                break;
            }
            char c = arr[begin];
            arr[begin] = arr[end];
            arr[end] = c;
            
            begin++;
            end--;
        }

        return String.valueOf(arr);
    }
}

367. 有效的完全平方数

难度简单

双指针暴力超时

class Solution {
    public boolean isPerfectSquare(int num) {
        if(num == 1){
            return true;
        }
        int begin = 1;
        int end = num / 2;
        int mid;
        while(begin <= end){
            mid = begin + (end - begin) / 2;
            long temp = mid * (long)mid;
            if(temp == num){
                return true; 
            }else if(temp > num){
                end--;
            }else{
                begin++;
            }
        }

        return false;
    }
}

不过如果用二分思想则可以通过。

class Solution {
    public boolean isPerfectSquare(int num) {
        if(num == 1){
            return true;
        }
        int begin = 1;
        int end = num / 2;
        int mid;
        while(begin <= end){
            mid = begin + (end - begin) / 2;
            long temp = mid * (long)mid;
            if(temp == num){
                return true; 
            }else if(temp > num){
                end = mid - 1;
            }else{
                begin = begin + 1;
            }
        }

        return false;
    }
}

emmm,换了种思路,还是超时了。依次去算各个数字的平方,如果平方值与num相等的话,则说明是;如果平方值比num要大时,则结束循环,返回false。

class Solution {
    public boolean isPerfectSquare(int num) {        
        int temp;
        for(int i = 1;i <= num / 2;i++){
            temp = i * i;
            if(num == temp){
                return true;
            }
            if(temp > num){
                break;
            }
        }
        return false;
    }
}

383. 赎金信

难度简单

因为题目说了两字符串中只包含小写字母,所以用一个长度为26的数组就可以解决。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] count = new int[26];

        for(char c : ransomNote.toCharArray()){
            count[c - 'a']++;
        }

        for(char c : magazine.toCharArray()){
            if(count[c - 'a'] > 0){
                count[c - 'a']--;
            }
        }

        for(int num : count){
            if(num > 0){
                return false;
            }
        }
        return true;
    }
}

387. 字符串中的第一个唯一字符

难度简单

比较简单的一题,借助一个set来判断前面有没有出现过字符,用indexOf来判断之后还有没有同一个字符。

class Solution {
    public int firstUniqChar(String s) {
        Set<Character> set = new HashSet<>();
        for(int i = 0;i < s.length();i++){
            char c = s.charAt(i);
            int index = s.indexOf(c, i + 1);
            if(!set.contains(c) && index == -1){
                return i;
            }
            set.add(c);
        }
        return -1;
    }
}

389. 找不同

难度简单

map是一种比较通用的解法。

class Solution {
    public char findTheDifference(String s, String t) {
        Map<Character,Integer> map1 = getCharMap(s);
        Map<Character,Integer> map2 = getCharMap(t);

        for(Map.Entry<Character, Integer> entry : map2.entrySet()){
            if(!map1.containsKey(entry.getKey()) || map1.get(entry.getKey()) != entry.getValue()){
                return entry.getKey();
            }
        }
        return '0';
    }

    public Map<Character, Integer> getCharMap(String str){
        Map<Character, Integer> map = new HashMap<>();
        for(char c : str.toCharArray()){
            if(map.containsKey(c)){
                map.put(c, map.get(c) + 1);
            }else{
                map.put(c, 1);
            }
        }
        return map;
    }
}

其次还可以把字符串转变成char数组,对其进行排序,再进行逐位的判断。

看了题解发现有更简单的做法。因为t中只添加了一个字符,所以除了添加的字符,在s和t组成的字符串中剩余的字符出现的次数一定是偶数次。所以这个题目就变成了在字符串中只出现过奇数次数的字符。把所有的字符进行一个异或,最后得到的值再转变成char就是结果。

class Solution {
    public char findTheDifference(String s, String t) {
        char[] arr1 = s.toCharArray();
        char[] arr2 = t.toCharArray();
        if(arr1.length == 0){
            return arr2[0];
        }

        int c = arr1[0] ^ arr2[0];
        for(int i = 1;i < arr1.length;i++){
            c ^= arr1[i] ^ arr2[i];
        }
        c ^= arr2[arr2.length - 1];
        return (char)c;
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值