【LeetCode】 Day 2

版权声明:--(●'◡'●)-- --(●ˇ∀ˇ●)-- https://blog.csdn.net/qq_36032149/article/details/84430931

657. Robot Return to Origin

给一个字符串,每个字符表示机器人的移动,其中U(上),D(下),L(左),R(右)
判断机器人最后是否在原点

    public boolean judgeCircle(String moves) {
        int x = 0, y = 0;
        for(char c: moves.toCharArray()){
            if(c == 'U')y--;
            else if(c == 'D')y++;
            else if(c == 'L')x--;
            else if(c == 'R')x++;
        }
        return x == 0 && y == 0;
    }

461. Hamming Distance

Hamming距离,即为两个数的二进制表示中的不同位的个数
例子:
1(0001),4(0100),第2位和第4位不同
5(0101), 3(0011),第2,3位不同

    public int hammingDistance(int x, int y) {
        int z = x ^ y;
        int c = 0;
        while(z != 0){
            //if((z & 1) == 1) c++;可简化为如下
            c += z & 1;
            z >>= 1;
        }
        return c;
    }

832. Flipping an Image

水平翻转图像,然后反色。
给定一个矩阵,水平方向反转,然后所有0和1互换。

    public int[][] flipAndInvertImage(int[][] A) {
        int len = A[0].length;
        for(int[] row : A){
            for(int i = 0; i <= len / 2; i++){
                if(i == len / 2) {//到中间时,直接01互换
                    row[i] ^= 1;
                    break;
                }
                int t = row[i];//水平对称位置的数交换,然后01互换
                row[i] = row[len - i - 1] ^ 1;
                row[len - i - 1] = t ^ 1;
            }
        }
        return A;
    }

617. Merge Two Binary Trees

合并两个二叉树

    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        TreeNode p = null;
        //对各种情况分类讨论,一共四种
        if(t1 == null && t2 == null){//此分类可不写,与最后的return p;(其中p==null)合并了。
            return null;
        }else if(t1 == null && t2 != null) {
            p = new TreeNode(t2.val);
            p.left = mergeTrees(null, t2.left);
            p.right = mergeTrees(null, t2.right);
        }else if(t1 !=null && t2 == null) {
            p = new TreeNode(t1.val);
            p.left = mergeTrees(t1.left, null);
            p.right = mergeTrees(t1.right, null);
        }else if(t1 != null && t2 != null) {
            p = new TreeNode(t1.val + t2.val);//累加当前节点值
            p.left = mergeTrees(t1.left, t2.left);//递归合并左边
            p.right = mergeTrees(t1.right, t2.right);//递归合并右边
        }
        return p;
    }

728. Self Dividing Numbers

A self-dividing number is a number that is divisible by every digit it contains.

For example, 128 is a self-dividing number because 128 % 1 == 0 ,128 % 2 == 0, and 128 % 8 == 0.

Also, a self-dividing number is not allowed to contain the digit zero.

Given a lower and upper number bound, output a list of every possible self dividing number, including the bounds if possible.
例如:

Input:
left = 1, right = 22
Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22]

    public List<Integer> selfDividingNumbers(int left, int right) {
        List<Integer> list = new ArrayList<>(right - left);//设置合理初始容量,防止经常扩容,影响性能
        for(int i = left; i <= right; i++) {
            int j = i;
            boolean b = true;//记录退出情况(正常退出(满足条件)/特殊情况退出(不满足条件))
            while(j != 0) {
                int k = j % 10;//取最后一位
                if(k == 0 || i % k != 0) {//如果有0,或存在不能整除的数,退出循环
                    b = false;
                    break;
                }
                j /= 10;    
            }
            if(b) list.add(i);//j==0正常退出循环的,就说明满足条件
        }
        return list;
    }

561. Array Partition I

Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), …, (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible.

Input: [1,4,3,2]
Output: 4
Explanation: n is 2, and the maximum sum of pairs is 4 = min(1, 2) + min(3, 4).

Note:

  • n is a positive integer, which is in the range of [1, 10000].
  • All the integers in the array will be in the range of [-10000, 10000].

数组成对组合,每一对中较小的值进行求和,要想尽可能地大,那每一对中的较大值和较小值就不能差太大,所以要让较小值尽可能接近较大值。常规思路,尝试对数组排序,那相邻两个必然是相差最小的。只需要取排序后的数组中下标为偶数的求和即可。
比如[1,4,3,2]=> [1,2,3,4]
min(1,2)+min(3,4) = 4 即为最大

    public int arrayPairSum(int[] nums) {
        Arrays.sort(nums);//排序
        int sum = 0;
        for(int i = 0; i < nums.length; i++){
            if(i % 2 == 0) sum += nums[i];
        }
        return sum;
    }

看了下其他解答,发现他们巧妙利用了Note提示的数组范围和长度,直接用O(n)复杂度的桶排序。

    public int arrayPairSum(int[] nums) {
        int[] arr = new int[20001];//题目条件n [1,10000]则2n [2,20000]
        for(int num : nums){//O(n)排序
            arr[num + 10000]++;//因为给的数为[-10000,10000],所以加10000防止越界
        }
        int sum = 0;
        for(int i = 0, j = 0; i < 20001; i++){//j用来记录当前数是第偶数还是奇数个。
            int a = arr[i];
            while(a-- > 0){//跳过a=0的位置
                if(j++ % 2 == 0){//第偶数个才进行累加
                    sum += i - 10000;    
                }
            }
        }
        return sum;
    }

852. Peak Index in a Mountain Array

找到第一个山峰,也就是比两边都大的数的索引
[0, 2, 0] => 1
[0, 1, 2] => 2
[2, 1, 0] => 0

    public int peakIndexInMountainArray(int[] A) {
        for(int i = 0; i < A.length - 1; i++){
            if(A[i] > A[i+1]){//比右边大
                if(i == 0) return 0;//如果是第一个直接返回
                if(A[i] > A[i-1]) {//比左边大
                    return i;
                }
            }
            if(i == A.length - 1 && A[i] > A[i-1) return i;//如果已经到了结尾,且比前一个数大,返回
        }
        return -1;//未找到
    }

官方给的最优答案,少了个边界判断(i < A.length - 1).感觉这个答案不太合理,比如a = [0,1,2,2],官方的结果是2,但a[2]=a[3]不符合题意。

    public int peakIndexInMountainArray(int[] A) {
        int i = 0;
        while (i < A.length - 1 && A[i] < A[i+1]) i++;
        return i;
    }

942. DI String Match

Given a string S that only contains “I” (increase) or “D” (decrease), let N = S.length.
Return any permutation A of [0, 1, ..., N] such that for all i = 0, ..., N-1:

  • If S[i] == “I”, then A[i] < A[i+1]
  • If S[i] == “D”, then A[i] > A[i+1]

例1:
Input: “IDID”
Output: [0,4,1,3,2]
例2:
Input: “III”
Output: [0,1,2,3]
例3:
Input: “DDI”
Output: [3,2,0,1]

思路,先从数字上去看看规律,
例如
IDID => [0,4,1,3,2]
把字符和数字对应看,
第一个I => 0,第二个I => 1,发现从小到大递增,
第一个D => 4,第二个D => 3,发现从大到小递减
可以发现,和I对应的每个数都是从0递增,和D对应的每个数,都是从N开始递减

    public int[] diStringMatch(String S) {
        int N = S.length();
        int[] r = new int[N + 1];//新建N+1长度数组,存放结果
        int j = N, i = 0, k = 0;
        for (char c : S.toCharArray()) {
            if (c == 'I') {//如果为I第 k 个从 i 开始自增
                //也可简化为r[k++] = i++;
                r[k] = i;
                k++;
                i++;
            } else {//第 k 个从 j 开始递减
                r[k++] = j--;
            }
        }
        //看了下答案,这里可以直接写成 r[N] = i; 因为只剩下最后一个数,i和j其实已经相遇了。
        if (S.charAt(N - 1) == 'I') {//因为循环只有n-1次,根据最后一个字符确定变化趋势,处理最后一个元素
            r[N] = i;
        } else {
            r[N] = j;
        }
        return r;
    }

922. Sort Array By Parity II

Given an array A of non-negative integers, half of the integers in A are odd, and half of the integers are even.

Sort the array so that whenever A[i] is odd, i is odd; and whenever A[i] is even, i is even.

You may return any answer array that satisfies this condition.

例:

Input: [4,2,5,7]
Output: [4,5,2,7]
Explanation: [4,7,2,5], [2,5,4,7], [2,7,4,5] would also have been accepted.

Note:

  1. 2 <= A.length <= 20000
  2. A.length % 2 == 0
  3. 0 <= A[i] <= 1000

奇数放到奇数下标,偶数放到偶数下标

    public int[] sortArrayByParityII(int[] A) {
        int[] R = new int[A.length];
        for(int i = 0, j = 0, k = 0; i < A.length; i++){
            if(A[i] % 2 == 0) {//偶数,放入偶下标位置
                R[2 * j] = A[i];
                j++;
            }else {//奇数,放入奇下标位置
                R[2 * k + 1] = A[i];
                k++;
            }
        }
        return R;
    }

猜你喜欢

转载自blog.csdn.net/qq_36032149/article/details/84430931