【LeetCode】第75场双周赛参赛实录

时间:2022-04-02 22:30-24:00

地址:竞赛 - 力扣 (LeetCode)

结局:本次依然是做了三道,而且是比较顺畅的做了三道,排名应该是刷新了本菜鸡的新高。继续努力把,第四题也小小的挣扎了一下,但最后还是提前放弃了。

【LeetCode】第75场双周赛参赛实录_第1张图片

6033. 转换数字的最少位翻转次数

【LeetCode】第75场双周赛参赛实录_第2张图片

【LeetCode】第75场双周赛参赛实录_第3张图片【LeetCode】第75场双周赛参赛实录_第4张图片

思路:这题还是让我愣神了半分钟,没有思路,作为第一题,简单难度,这个所谓的翻转操作,应该不会那么复杂。很快我就反应过来,可以把该问题转换为两步,1,通过异或,拿到两个数各数位是否不同,也即是否需要翻转;2,通过一些手段,统计出异或后数字中1的个数,即为翻转次数。

 public int minBitFlips(int start, int goal) {
        int temp = start^goal;
        int res = 0;
        while(temp>0){
            res+=temp%2;
            temp=temp/2;
        }
        return res;
    }

后续整理:思路没错,熟悉的话,可以无限简洁。

public int minBitFlips(int start, int goal) {
		return Integer.bitCount(start ^ goal);
	}

6034. 数组的三角和

【LeetCode】第75场双周赛参赛实录_第5张图片【LeetCode】第75场双周赛参赛实录_第6张图片

思路:这题读懂后,第一反应就是模拟,也不复杂,就在原数组上计算就是了,因为我们预先能够知道计算次数是nums.length-1次,然后每次模拟,最后取nums[0]即可。但后面直觉,应该是可以用一个基于nums.length和i的表达式,得到位置为i的数字的计算次数的。不过想了一会没想出来,就放弃了,还是采用的模拟的写法。

大致就是这样的一个实现,参考文档:力扣

【LeetCode】第75场双周赛参赛实录_第7张图片

public int triangularSum(int[] nums) {
        int len = nums.length;
        for(int i=0;i<=nums.length-1;i++){
            for(int j=0;j

后续整理:果然还是找到了纯数学的思路,截图学习。参考: 第 75 场力扣夜喵双周赛 - 力扣(LeetCode)

【LeetCode】第75场双周赛参赛实录_第8张图片

6035. 选择建筑的方案数

【LeetCode】第75场双周赛参赛实录_第9张图片【LeetCode】第75场双周赛参赛实录_第10张图片

思路:初看还是有点懵逼,但很快就意识到了,其实有且仅有两种101和010两种情况。一个思路是遍历数组,当前数字作为中间数,如当前数字为0,计算其左边1的数量c1右边1数量c2,c1*c2即为以该数字为中间数字的方案数;当前数字为1同理。那如何很快的就算左1右1的数量呢,可以用类似于前缀和的思路,用一个数组来存,一次遍历即可。最终是一个O(n)的算法。

//赶时间,写的有点low
public long numberOfWays(String s) {
        char[] cs = s.toCharArray();
        int len = cs.length;
        long res = 0;
        int[] left0 = new int[len];//记录当前位置左边有多少个0
        int[] left1 = new int[len];//记录当前位置左边有多少个1
        int[] right0 = new int[len];//记录当前位置右边有多少个0
        int[] right1 = new int[len];//记录当前位置右边有多少个1
        int count0=0;
        int count1=0;
        for(int i=1;i=0;i--){
            if(cs[i+1]=='0'){
                right0[i]=++count0;
                right1[i]=count1;
            }
            if(cs[i+1]=='1'){
                right0[i] = count0;
                right1[i]=++count1;
            }
        }
        for(int i=0;i

后续整理:主流思路。但代码还可以做一些简化。看到一个很直观但又很优秀但解法,一看就懂的那种。

using ll = long long;

class Solution {
public:
    ll numberOfWays(string s) {
        int n = s.size();
        ll ans = 0;
        ll z = 0, o = 0, zo = 0, oz = 0, zoz = 0, ozo = 0;
        for (char c : s) {
            int i = c - '0';
            if (i == 0) {
                zoz += zo;
                oz += o;
                z++;
            } else {
                ozo += oz;
                zo += z;
                o++;
            }
        }
        return zoz + ozo;
    }
};

作者:吴自华
链接:https://leetcode-cn.com/circle/discuss/gkiO22/view/mI626f/

6036. 构造字符串的总得分和

【LeetCode】第75场双周赛参赛实录_第11张图片【LeetCode】第75场双周赛参赛实录_第12张图片

思路:这题很显然有一个O(n*n)的粗暴算法可以直接处理(先附在下面),但尝试了两次,都是直接超时。便怀疑有什么未知的,更为先进的算法,去百度了一阵kmp,整到23:30,没有得到什么启发,就放弃了。。又一次意料之中的卡在了最后一题。

public long sumScores(String s) {
        long res = 0;
        int len = s.length();
        for(int i=0;i

后续整理:果然,有一种扩展KMP算法(Z算法),很模板的一个题。可以参考这边文章看看。以我kmp都写不出来的实力,花了好一阵才看懂,但可能还是没法写出来。https://oi-wiki.org/string/z-func/

你可能感兴趣的:(2.数据结构与算法,leetcode,java)