力扣第34场双周赛

5491. 矩阵对角线元素的和

给你一个正方形矩阵 mat,请你返回矩阵对角线元素的和。

请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和。

思路

简单题,要主要每一行都有两个数值,两个数字的横坐标是有关联的,如果正方形的边的长度是奇数的话,那么,我们需要减去中间的那个重复计算的那个数值。

代码

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

结果

ac了,没什么难的。

5492. 分割字符串的方案数

给你一个二进制串 s (一个只包含 0 和 1 的字符串),我们可以将 s 分割成 3 个 非空 字符串 s1, s2, s3 (s1 + s2 + s3 = s)。

请你返回分割 s 的方案数,满足 s1,s2 和 s3 中字符 ‘1’ 的数目相同。

由于答案可能很大,请将它对 10^9 + 7 取余后返回。

思路

要想分割1的个数相同的字符串,就得保证1的个数是3的倍数。假设1的个数不是3的倍数,那么就直接返回0即可。

假设数目是3的倍数了,那么我们要考虑哪些地方可以切割的,我们必须找出刚刚好到1的个数的三分之一那个地方的数目,然后在这个1的后面,只要是0我们就可以任意切割。同理,我们需要从后面开始往前找,找到1的数目的三分之一的那个1之后,它与下一个1之间的0的个数就会决定我们切得种类数目。而且这两部0永远不会相交,因为中间一定有1间隔开。我们只需要计算出这两部分的0的数目,并加1,然后再乘积对于1000000007取余即可。

假设整个字符串都是0,那么总共有n-1个地方可以切割成0的字符串,我们只需要计算组合n-1取2,就是他的数目。

以上的计算过程中,主要不要爆整形数目了。

代码


class Solution {
    public int numWays(String s) {
        int count=0;
        int length=s.length();
        int result[]=new int[length];
        char temp;
        for (int i=0;i<length;++i)
        {
            temp=s.charAt(i);
            result[i]=(int)(temp-48);
            if (temp=='1')
                ++count;
        }
        if (count%3!=0)
            return 0;

        if (count==0)
        {
            long g=((long)(length-1)*(length-2)/2)%1000000007;
            return (int)g;

        }
        int first=0;
        int first_index=-1;
        int temp_num=count/3;
        for (int i=0;i<length;++i)
        {
            first+=result[i];
            if (first==temp_num)
            {
                first_index=i;
                break;
            }
        }

        int second=0;
        int second_index=-1;
        for (int i=length-1;i>=0;--i)
        {
            second+=result[i];
            if (second==temp_num)
            {
                second_index=i;
                break;
            }
        }

        int num_1=0;
        for (int g=first_index+1;g<length-1;++g)
        {
            if (result[g]!=1)
                ++num_1;
            else
                break;
        }

        int num_2=0;
        for (int g=second_index-1;g>=0;--g)
        {
            if (result[g]!=1)
                ++num_2;
            else
                break;
        }
        ++num_1;
        ++num_2;
        long l=((long)(num_1%1000000007) *(num_2%1000000007))%1000000007;
        return (int)l;
    }
}

结果

ac了,简单的模拟题,主要是要注意过程中不要超过整形的问题和如何找出它具体怎么切这个地方是最关键的。

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

给你一个整数数组 arr ,请你删除一个子数组(可以为空),使得 arr 中剩下的元素是 非递减 的。

一个子数组指的是原数组中连续的一个子序列。

请你返回满足题目要求的最短子数组的长度。

思路

我们要保留左边的升序序列,最少为1个,并且保留右边的升序序列,最少也为1个。然后,我们只需要在这个升序序列中,再找出那些影响升序序列的区间并把他们给去除掉,这样子就可以找出升序序列。

代码

class Solution {
    public int findLengthOfShortestSubarray(int[] arr) {
        int l1Right = -1, l2Left = arr.length;
        for (int i = 1; i< arr.length; ++i) {
            if (arr[i] < arr[i-1]) {
                l1Right = i-1;
                break;
            }
        }
        if(l1Right == -1) {
            l1Right = arr.length-1;
        }
        for (int i = arr.length-1; i > l1Right; --i) {
            if (arr[i] < arr[i-1]) {
                l2Left = i;
                break;
            }
        }

        return minDelteArray(l1Right, l2Left, arr)+l2Left-l1Right-1;
    }

    public int minDelteArray(int l1Right, int l2Left, int[] arr) {
        if (l1Right < 0 || l2Left >= arr.length) {
            return 0;
        }
        if (arr[l1Right] <= arr[l2Left] ) {
            return 0;
        }
        return Math.min(minDelteArray(l1Right-1, l2Left,arr)+1,minDelteArray(l1Right, l2Left+1, arr)+1);
    }
}

结果

这是上面别人的利用递归做的代码,挺优秀的,借了过来。不是我写的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值