Leetcode刷题 2021.02.12

Leetcode刷题 2021.02.12

  • Leetcode119 杨辉三角 II
  • Leetcode870 优势洗牌
  • Leetcode923 三数之和的多种可能

Leetcode119 杨辉三角 II

给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。

每日一题,杨辉三角应该是学编程的入门题了。记得上大一的时候,编个杨辉三角的作业,编了一晚上才写出来。真是难忘的回忆啊。

class Solution {
     
    public List<Integer> getRow(int rowIndex) {
     
        List<Integer> prev = new ArrayList<>();
        for(int i = 0; i <= rowIndex; i++){
     
            List<Integer> temp = new ArrayList<>();
            for(int j = 0; j <= i; j++){
     
                if (j == 0 || j == i){
     
                    temp.add(1);
                }else{
     
                    temp.add(prev.get(j - 1) + prev.get(j));
                }
            }
            prev = temp;
        }
        return prev;
    }
}

Leetcode870 优势洗牌

给定两个大小相等的数组 A 和 B,A 相对于 B 的优势可以用满足 A[i] > B[i] 的索引 i 的数目来描述。

返回 A 的任意排列,使其相对于 B 的优势最大化。

话说贪心的思想感觉就是生活中的经验。比如这题就是已知对方的战斗力,要安排己方的战斗力能在回合制游戏中打过对面。那么可以先进行排序,如果己方有能战胜对方的,就安排一个人和对方打。如果没有打得过的,就安排一个最弱的下等马去打。

class Solution {
     
    public int[] advantageCount(int[] A, int[] B) {
     
        int n = A.length;
        int[] res = new int[n];
        //对A,B进行排序,对B排序记录一下位置的索引
        Arrays.sort(A);
        int[][] help = new int[n][2];
        for(int i = 0; i < n; i++){
     
            help[i][0] = B[i];
            help[i][1] = i;
        }
        Arrays.sort(help, (x, y) -> (x[0] - y[0]));
        int i = 0, j = n - 1, k = n - 1;
        //按贪心的思路遍历
        while (i <= j){
     
            if (help[k][0] < A[j]){
     
                res[help[k][1]] = A[j];
                j--;
            }else{
     
                res[help[k][1]] = A[i];
                i++;
            }
            k--;
        }
        return res;
    }
}

Leetcode923 三数之和的多种可能

给定一个整数数组 A,以及一个整数 target 作为目标值,返回满足 i < j < k 且 A[i] + A[j] + A[k] == target 的元组 i, j, k 的数量。

由于结果会非常大,请返回 结果除以 10^9 + 7 的余数。

和经典的三数之和的做法基本一致,就是要额外考虑一种情况。

class Solution {
     
    final int mod = 1000000007;
    public int threeSumMulti(int[] arr, int target) {
     
    	//三数之和要先排下序
        Arrays.sort(arr);
        int n = arr.length, res = 0;
        for(int k = 0; k < arr.length; k++){
     
        	//小剪枝
            if (arr[k] > target) break;
            int i = k + 1, j = n - 1;
            //排序玩用双指针
            while (i < j){
     
                int temp = arr[i] + arr[j] + arr[k];
                //大于目标值,就让大的减一,反之相同
                if (temp > target){
     
                    j--;
                }else if (temp < target){
     
                    i++;
                    //如果等于目标值,且arr[i] != arr[j],计算下有多少个相同的元素
                }else if (arr[i] != arr[j]){
     
                    int countI = 1, countJ = 1;
                    while (i < j - 1 && arr[i] == arr[i + 1]){
     
                        countI++;
                        i++;
                    }
                    while (i < j - 1 && arr[j] == arr[j - 1]){
     
                        countJ++;
                        j--;
                    }
                    i++;
                    j--;
                    res += countI * countJ;
                    res %= mod;
                }else {
     
                    //不想等的可能性,比如[1,1,2,2,2,2],相等于从4个挑两个,就是C42
                    res += (j - i + 1) * (j - i) / 2;
                    res %= mod;
                    break;
                }
            }
        }
        return res;
    }
}

你可能感兴趣的:(刷题)