天天看點

【LeetCode】 Day 2

文章目錄

    • 657. Robot Return to Origin
    • 461. Hamming Distance
    • 832. Flipping an Image
    • 617. Merge Two Binary Trees
    • 728. Self Dividing Numbers
    • 561. Array Partition I
    • 852. Peak Index in a Mountain Array
    • 942. DI String Match
    • 922. Sort Array By Parity II

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;
    }