Leetcode 第34场 双周赛20.9.5 5491/5492/5493/5494

5491. 矩阵对角线元素的和

难度:打卡题

考点:初学程序人

思想:两边对角线累加然后删除相交的值(奇数行删,偶数行不删)

class Solution {
    public int diagonalSum(int[][] mat) {
        int n = mat.length;
        int res = 0;
        for(int i = 0; i < n; ++i){
            res += mat[i][i];
            res += mat[i][n - 1 - i];
        }
        if(n % 2 == 1)res -= mat[n / 2][n / 2];
        return res;
    }
}

5492. 分割字符串的方案数

难度:打卡题

考点:简单乘法数学题

思想:1的个数不是3的倍数则不存在直接返回0,是3的倍数则将1分为三个区域abc,计算a区域的末尾和b区域的头b区域的末位c区域的头,然后相乘则得到分割种类数

class Solution {
    int mod = 1000000007;
    public int numWays(String s) {
        int cnt = 0;
        int n = s.length();
        for(int i = 0; i < n; ++i){//计算1的个数
            if(s.charAt(i) == '1')cnt++;
        }
        int cnt1 = n - cnt;//得到0的个数
        if(cnt1 == n)return (int)(((long)(n - 1) * (n - 2)) % mod) / 2;//全0则返回n - 1
        if(cnt % 3 != 0)return 0;//判断是否成立
        int avg = cnt / 3;
        int a1 = -1, b1 = -1, a2 = -1, b2 = -1;
        cnt = 0;
        for(int i = 0; i < n; ++i){
            if(s.charAt(i) == '1'){
                cnt++;
                if(cnt == avg)a1 = i;
                if(cnt > avg && b1 == -1)b1 = i - 1;
                if(cnt == (avg << 1))a2 = i;
                if(cnt > (avg << 1) && b2 == -1)b2 = i - 1;
            }
        }
        return (int)((long)(b1 - a1 + 1) * (b2 - a2 + 1) % mod);
    }
}

5493. 删除最短的子数组使剩余数组有序

难度:中等

思想:题意是只删除一组整数数组则达到要求,我们只需要找到从头开始的递增序列的尾指针和从尾开始的递减序列的头指针,然后将前一个序列作为遍历,从前一个序列的每个点作为目标点,在后序列中二分查找,从而计算出两个点的差值(就是需要删除的数组),从中找到最小的数组即可。

考点:双指针+二分+一些特殊情况的判定能力

时间复杂度:O(nlogn)

class Solution {
    int bs(int[] arr, int l, int r, int num){
        while(l < r){
            int mid = l + r >> 1;
            if(arr[mid] < num)l = mid + 1;
            else r = mid;
        }
        return l;
    }
    public int findLengthOfShortestSubarray(int[] arr) {
        int n = arr.length;
        int index1 = 0;
        int index2 = n - 1;
        int i, j;
        for(i = 1; i < n; ++i){
            if(arr[i] >= arr[i - 1])index1 = i;
            else break;
        }
        for(j = n - 1; j > 0; --j){
            if(arr[j - 1] <= arr[j])index2 = j - 1;
            else break;
        }
        if(index2 <= index1)return 0;
        int min = Math.min(n - 1 - index1, index2);
        for(i = index1; i >= 0; --i){
            int pos = bs(arr, index2, n - 1, arr[i]);
            if(arr[i] <= arr[pos])
                min = Math.min(min, pos - i - 1);
            else if(arr[i] > arr[pos])
                min = Math.min(min, pos - i);
        }
       return min;
    }
}

5494. 统计所有可行路径

难度:中等

思想:从start到finish的路径,且路径上的消耗不能超过fuel。

考点:记忆化搜索+dfs

时间复杂度:O(nlogn)

class Solution {
    int mod = 1000000007;
    HashMap<String, Long>map = new HashMap<>();
    public int countRoutes(int[] locations, int start, int finish, int fuel) {
        return (int)dfs(locations, start, finish, fuel) % mod;
    }
    public long dfs(int[] a, int start, int finish, int fuel){
        long res = 0;
        String key = start + " " +finish + " " + fuel;
        if(map.containsKey(key)){
            return map.get(key);
        }
       
        for(int i = 0; i < a.length; ++i){
            if(i == start)continue;
            int le = fuel - Math.abs(a[start] - a[i]);
            if(le >= 0){
                res += dfs(a, i, finish, le);
                res %= mod;
            }
        }
        if(start == finish){
            res++;
            res %= mod;
        }
        map.put(key, res);
        return res;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值