【LeetCode每日一题】2024年8月第二周(上)

news2024/12/30 2:40:19

 2024.8.5 困难

链接:600. 不含连续1的非负整数

(1)题目描述:

(2)示例

(3)分析

思路1:

        题目要求的数值,是将数二进制转换后,不存在连续的1,那么我们初步分析:每一个数的最高位,由下一位来决定。第二位为0时:下一位可为0、1;而第二位为1时:下一位只为0

        于是直接进行转换,按照n转换为2进制的位数后的长度,进行递归拼接即可。最后统计,只要转换后的数字,小于等于n就行。

        这种方法,虽然可行,但在10^9数据量面前,显然不够看的,运行n=10^9时,耗时5s。

思路2:

        因为实际上控制大小的是n转换为2进制后的长度,我们去观察,不同长度下,它的最大结果。(即当前长度下,所包含的个数)

        ① 我们惊人的发现,他们的结果满足类似斐波那契数列的特点,因此我们完全可以写写出长度和个数的方程:dp[i] = dp[i - 1] + dp[i - 2]; (dp用于存储个数,i为n二进制长度)

        ② 而进一步发现,我们可以得到:只要当前i位(从0开始)为1,那么结果中就一定包含:dp[i]个值:

        怎么理解?

        1)我们将dp结果看作是:i位1的数总和,比如符合题目可存在的最大数 101010(含自身)-- 6位 和1000000(不含自身) 皆对应 d[6]=d[5]+d[4] ==》d4=d3+d2 d2=d1+d0 =d1+1

       2) 而实际上d[6],同时满足:d[6]=d[5]+d[3]+d[2]=d[5]+d[3]+d[1]+1 ,很显然,这是和101010的1所在位数对应的,

        3)那么对101001 6位:拆分为:100000 + 001000+ 000001 首先包含5位情况下的所有个数,再比对1000,再比对1==》100000:dp[5] 001000:dp[3] 000001:dp[0]

        于是乎,我们得到:可以直接由当前n的二进制转换,得到最终的结果!

        

(4)代码

我把两种都写上:

//思路2:
class Solution {
    // 动态规划的方法计算不含连续 1 的二进制数的数量
    public static int findIntegers(int n) {
        int[] dp = new int[32];//32位,最大n在此范围内
        dp[0] = 1;//初始化数据
        dp[1] = 2;
        // 预处理 dp 数组
        for (int i = 2; i < 32; i++) {
            dp[i] = dp[i - 1] + dp[i - 2]; //结果满足类似斐波那契数列的形式
        }

        int temp = 0;//检测最终值是否为2个1的情况
        int result = 0;
        //由上文遍历的思路,如此可以确定,只要当前i位为1,那么结果中就一定包含:dp[i]个前一位的东西
        // 怎么理解://将dp结果看作是:i位1的数总和,比如可存在的最大数 101010(含自身) 6位 和1000000(不含自身) 皆对应d[6]=d[5]+d[4] ==》d4=d3+d2 d2=d1+d0 =d1+1
        // 而实际上d[6],同时满足:d[6]=d[5]+d[3]+d[2]=d[5]+d[3]+d[1]+1 ,很显然,这是和101010的1所在位数对应的,
        // 那么对101001 6位:拆分为:100000 + 001000+ 000001 首先包含5位情况下的所有个数,再比对1000,再比对1==》
        // 100000:dp[5] 001000:dp[3] 000001:dp[0]

        // 遍历 n 的二进制表示
        for (int i = 31; i >= 0; i--) {
            if ((n & (1 << i)) != 0) {  // 当前位是 1按照上文输出
                // 实际上类如:11000 和10101相互等价皆为d[4]+d[3],所以不用else了……
                result += dp[i];
                if (temp == 1) {  // 检测到连续的两个 1
                    return result;
                }
                temp = 1;
            } else {
                temp = 0;
            }
        }
        return result + 1;  // 包含 n 本身
    }

    // 测试
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        int sum = findIntegers(1000000000);
        System.out.println(sum);
        System.out.println("time: " + (System.currentTimeMillis() - start) + "ms");

    }
}
//思路1:
class Solution1 {
    //遍历,直接超时!
    //思路:没有连续的1,那么每一个数的最高位:由下一位来决定。第二位为0时:可为0、1;1时:只为0.
    //统计时,只要大小小于就行。
    public static int findIntegers(int n) {
        int sum = 0;
        int len = Integer.toBinaryString(n).length();//Integer.toBinaryString:2进制转换
        List<String> str = Arrays.asList("0", "1");//赋初值
        if (n < 2) return n + 1;
        else {
            for (int i = 0; i < len; i++) {
                str = getS(str);
            }
            List<String> re = str.stream().sorted().filter(s -> n >= Integer.valueOf(s, 2)).collect(Collectors.toList()); 
            sum = re.size();
        }
        return sum;
    }

    public static List<String> getS(List<String> str) {
        List<String> stringList = new ArrayList<>();
        str.stream().forEach(s -> {
            if (s.charAt(0) == '0') {
                stringList.add("0" + s);
                stringList.add("1" + s);
            } else {
                stringList.add("0" + s);
            }
        });
        return stringList;
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        int sum = findIntegers(100000000);
        System.out.println(sum);
        System.out.println("time: " + (System.currentTimeMillis() - start) + "ms");
    }
}

(5)碎碎念

题目越短,事儿越大……一个题看了挺久的

 2024.8.06 中等

链接:3129. 找出所有稳定的二进制数组 I

(1)题目描述:

(2)示例

(3)分析

        题目中,limit限制着0或1的最大连续出现次数(最大为limit),我们按照顺序放0、1时,最后一位0/1是由:前一位没达到limit限制0、1添加0/1而来,转换为可以计算的,便是:不受限制(即所有)的0、1,减去不符合要求的(出现次数大于limit的。)

        于是我们捋清楚了思路,而超过限制的明显由0或1组成,因此我们分类来讨论:

        ① 0结尾的:sum0 = 放0前以0/1结尾的总和  -  前面放了limit+1个0,以1结尾的

        ② 1结尾的:sum1 = 放1前以0/1结尾的总和  -  前面放了limit+1个1,以0结尾的

        最后结果,sum1 sum0

        而此皆存在一个前提,当前放入的0/1总数,大于limit,如此才可能有重合。因此需要来表示当前存入的0/1数量==》

        于是乎,大致思路有了,整体运用动态规划,设置i用于表示当前存入0的数量,j表示存入1的数量。再次观看案例,考虑到可能存在只放入同一个值(同时不超过limit和个数),其结果只有一种情况,由此可以设定初始值。

        贴一张官方图:

(4)代码

class Solution {
    public int numberOfStableArrays(int zero, int one, int limit) {
        final long MOD = 1000000007;
        long[][][] dp = new long[zero + 1][one + 1][2];
        for (int i = 0; i <= Math.min(zero, limit); i++) {
        // 初始化,设置最基础的可能性,只填充同一个值时,只有一种情况。赋值1;
            dp[i][0][0] = 1;
        }
        for (int i = 0; i <= Math.min(one, limit); i++) {
            dp[0][i][1] = 1;
        }
        for (int i = 1; i <= zero; i++) {
            for (int j = 1; j <= one; j++) {
                if (i > limit) {
                    dp[i][j][0] = dp[i - 1][j][0] + dp[i - 1][j][1] - dp[i - limit - 1][j][1];
                } else {
                    dp[i][j][0] = dp[i - 1][j][0] + dp[i - 1][j][1];
                }
                // dp[i][j][0]%= MOD;不这样写是因为,数据量大了后,会溢出,对应的数据变成负数了……
                dp[i][j][0] = (dp[i][j][0] % MOD + MOD) % MOD;// 数据回正
                if (j > limit) {
                    dp[i][j][1] = dp[i][j - 1][0] + dp[i][j - 1][1] - dp[i][j - limit - 1][0];
                } else {
                    dp[i][j][1] = dp[i][j - 1][0] + dp[i][j - 1][1];

                }
                dp[i][j][1] = (dp[i][j][1] % MOD + MOD) % MOD;

            }
        }
        return (int) ((dp[zero][one][0] + dp[zero][one][1]) % MOD);
    }
}

(5)碎碎念

你管这叫中等题?一开始我想的是用组合和乘法原理的思想,希望得到一个通解公式,类似那种伯努利装错信的思想,后来发现得不到有效的思路……还是太菜了。然后看了题解的提示,才有的思路。

 2024.8.07 困难

链接:3130. 找出所有稳定的二进制数组 II

(1)题目描述:

(2)示例

(3)分析

        这题目,实际上就是上面的,只不过数据量变大了,但是咱们的思路是完全正确的,而且取模后数据也不会超,直接试一试就行。Ctrl c v。

        这里放一个灵神的解析,采用:容斥原理+乘法原理 ,我一开始的思想就类似这个,但没求出来,看到解析发现本来思路的可行性,灵神nb!

 灵茶山艾府解析 - 力扣(LeetCode)

(4)代码

. - 力扣(LeetCode) 贴个代码。

class Solution {
    private static final int MOD = 1_000_000_007;
    private static final int MX = 1001;

    private static final long[] F = new long[MX]; // f[i] = i!
    private static final long[] INV_F = new long[MX]; // inv_f[i] = i!^-1

    static {
        F[0] = 1;
        for (int i = 1; i < MX; i++) {
            F[i] = F[i - 1] * i % MOD;
        }

        INV_F[MX - 1] = pow(F[MX - 1], MOD - 2);
        for (int i = MX - 1; i > 0; i--) {
            INV_F[i - 1] = INV_F[i] * i % MOD;
        }
    }

    public int numberOfStableArrays(int zero, int one, int limit) {
        if (zero > one) {
            // swap,保证空间复杂度为 O(min(zero, one))
            int t = zero;
            zero = one;
            one = t;
        }
        long[] f0 = new long[zero + 3];
        for (int i = (zero - 1) / limit + 1; i <= zero; i++) {
            f0[i] = comb(zero - 1, i - 1);
            for (int j = 1; j <= (zero - i) / limit; j++) {
                f0[i] = (f0[i] + (1 - j % 2 * 2) * comb(i, j) * comb(zero - j * limit - 1, i - 1)) % MOD;
            }
        }

        long ans = 0;
        for (int i = (one - 1) / limit + 1; i <= Math.min(one, zero + 1); i++) {
            long f1 = comb(one - 1, i - 1);
            for (int j = 1; j <= (one - i) / limit; j++) {
                f1 = (f1 + (1 - j % 2 * 2) * comb(i, j) * comb(one - j * limit - 1, i - 1)) % MOD;
            }
            ans = (ans + (f0[i - 1] + f0[i] * 2 + f0[i + 1]) * f1) % MOD;
        }
        return (int) ((ans + MOD) % MOD); // 保证结果非负
    }

    private long comb(int n, int m) {
        return F[n] * INV_F[m] % MOD * INV_F[n - m] % MOD;
    }

    private static long pow(long x, int n) {
        long res = 1;
        for (; n > 0; n /= 2) {
            if (n % 2 > 0) {
                res = res * x % MOD;
            }
            x = x * x % MOD;
        }
        return res;
    }
}

//作者:灵茶山艾府
//链接:https://leetcode.cn/problems/find-all-possible-stable-binary-arrays-ii/solutions/2758868/dong-tai-gui-hua-cong-ji-yi-hua-sou-suo-37jdi/
//来源:力扣(LeetCode)
//著作权归作者所有。非商业转载。

(5)碎碎念

今天早上,在地铁上打开Leetcode app,发现题目和昨天一样,直接在手机上写了,正好检测昨天的记忆,写完正好地铁到站,案例也过了,虽然运行时间和内存排名排不到前面罢了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1987898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python 爬取 ip 代理网站 获取ip代理池

爬取的网站&#xff1a;免费私密代理IP_IP代理_HTTP代理 - 快代理 示例代码&#xff1a; import jsonimport requests import time,reclass daili:# 1.发送请求&#xff0c;获取响应def send_request(self, page):print("正在抓取第{}页".format(page))# 目标网页&…

设计模式19-状态模式

设计模式19-状态模式&#xff08;State Pattern&#xff09; 写在前面状态变化模式 动机定义与结构定义结构 C代码推导优缺点应用总结 写在前面 状态变化模式 在组建构建过程中&#xff0c;某些对象的状态经常面临着变化。如何对这些变化进行有效的管理呢&#xff1f;同时又w…

特征向量可视化方法介绍

在最近的研究中&#xff0c;实验需要结合可视化进行解释分析&#xff0c;于是大致上了解了下目前一些特征可视化的工具&#xff0c;主要分为四种类型&#xff1a;热力图、散点图、线性图和雷达图&#xff0c;并将相应的基础绘制方法做一个简单的总结。 1 热力图&#xff08;Hea…

向量检索的3种方式

本文介绍向量检索服务如何通过控制台、SDK、API三种不同的方式检索向量。 控制台方式 登录向量检索服务控制台。 在左侧导航栏单击Cluster列表&#xff0c;选中需要检索向量的Collection&#xff0c;单击Collection详情。 在左侧二级导航栏&#xff0c;单击相似向量搜索&…

Leetcode - 136双周赛

目录 一&#xff0c;3238. 求出胜利玩家的数目 二&#xff0c;3239. 最少翻转次数使二进制矩阵回文 I 三&#xff0c;3240. 最少翻转次数使二进制矩阵回文 II 四&#xff0c;3241. 标记所有节点需要的时间 一&#xff0c;3238. 求出胜利玩家的数目 本题直接暴力求解&#x…

springboot招聘管理系统-计算机毕业设计源码26241

摘 要 随着企业的发展和竞争的加剧&#xff0c;人才招聘成为企业人力资源管理中的重要环节。为了提高招聘效率、降低招聘成本&#xff0c;同时提升招聘过程的透明度和公平性&#xff0c;设计并实现一款基于 SpringBoot 的招聘管理系统具有重要的现实意义。 本系统旨在提供一个全…

【MySQL】MySQL常见命令大全

目录 前言一、DQL二 、DML(数据操作语言)部分2.1 插入数据&#xff1a;2.2 更新数据:2.3 删除数据&#xff1a;2.4 创建 create 三、修改 alter四、删除 drop五、表的复制六、常见数据类型 前言 大家好&#xff0c;不知道前面的20题大家写的怎么样&#xff0c;前面分享的20题是…

数据库技术如何增强 AI 大模型?来直播间同拓数派开启探索之旅!

如今&#xff0c;大模型应用正以前所未有的速度改变着各个行业。从自然语言处理、计算机视觉到多模态任务的解决方案&#xff0c;AI 技术已经成为推动业务创新的核心力量。然而&#xff0c;大模型的训练和推理需要处理大量高维度的向量数据&#xff0c;传统数据库在面对这些需求…

3.串口(UART)

串口理论部分可看51部分&#xff1a;链接 数据帧 帧头(2字节&#xff0c;例如AA、BB) 数据长度&#xff08;2字节&#xff09; 数据 CRC16校验&#xff08;2字节&#xff09; 帧尾&#xff08;2字节&#xff09; 代码编写 串口一发送命令控制LED灯(PB5、PE5) LED灯、串口、…

python:基于YOLO框架和遥感图像的目标检测

作者&#xff1a;CSDN _养乐多_ 本文将介绍如何通过YOLO框架和遥感图像进行目标检测的代码。 文章目录 一、数据集下载与格式转换1.1 NWPU VHR-10&#xff08;73.1 MB&#xff09;1.2 DIOR&#xff08;7.06 GB&#xff09;1.3 配置data.yaml 二、训练三、训练结果 一、数据集…

揭秘 NKAbuse:一种滥用 NKN 协议的新型多平台威胁

写在前面的话 在卡巴斯基全球紧急响应团队&#xff08;GERT&#xff09;和GReAT处理的一次网络安全事件应急响应过程中&#xff0c;研究人员发现了一个名为“KNAbuse”的新型多平台网络威胁。这款恶意软件利用了NKN技术在对等节点之间进行数据交换&#xff0c;功能上相当于一种…

NC 合并k个已排序的链表

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 描述 合并 k 个升序…

Ubuntu系统安装docker和docker-compose并解决拉取镜像超时失败问题

安装docker 1、添加Docker官方的GPG密钥: curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - 2、添加docker的软件源 sudo add-apt-repository "deb [archamd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release …

嵌入式软件--C语言高级 DAY 8 函数

函数是C语言尤为重要的知识点&#xff0c;再嵌入式的学习过程中&#xff0c;对51和32的单片机的学习是重中之重。 一、函数的基本概念 1.介绍 函数是一种可重复使用的代码块&#xff0c;用于执行特定的任务或操作。 函数允许我们将代码逻辑组织成独立的单元&#xff0c;从而…

Python酷库之旅-第三方库Pandas(069)

目录 一、用法精讲 276、pandas.Series.dt.is_quarter_start属性 276-1、语法 276-2、参数 276-3、功能 276-4、返回值 276-5、说明 276-6、用法 276-6-1、数据准备 276-6-2、代码示例 276-6-3、结果输出 277、pandas.Series.dt.is_quarter_end属性 277-1、语法 …

知乎ip地址怎么改到别的城市去

知乎全面上线显示用户IP属地功能&#xff0c;这意味着用户可以在知乎上看到其他用户发布内容时的IP属地信息&#xff0c;这有助于增加信息的透明度和减少误解&#xff0c;但同时也容易暴露其隐私。有时出于保护隐私、避免地域限制或参与特定话题讨论的需求&#xff0c;我们可能…

【实战】文件加密器进行逆向

前言 实战可以大大提高自己&#xff0c;学习技术的目的就是能够在实战中运用。 本次实战与实际息息相关&#xff0c;该软件具有加密某文件的功能。 界面还挺好看的&#xff0c;功能很简单&#xff0c;输入文件和PIN(4位&#xff09;进加解密。 这是被加密的文件 需要将其进行…

经纬恒润荣获小米汽车优秀质量奖!

小米SU7上市已超百天&#xff0c;在品质经过客户严选的同时&#xff0c;产量与交付量屡创新高&#xff0c;6-7月连续两个月交付量均超过10000台。为奖励对小米汽车质量和交付做出卓越贡献的合作伙伴团队及个人&#xff0c;小米向质量表现突出的供应商授予了优秀质量奖。经纬恒润…

第22课 Scratch入门篇:猫咪跑步(超长背景实现方法)

猫咪跑步(超长背景实现方法) 故事背景&#xff1a; 在广阔的草坪上有一只小猫&#xff0c;按下键盘的左右键&#xff0c;小猫不停的奔跑。。。 程序原理&#xff1a; 这个小猫的奔跑&#xff0c;实际是背景的移动&#xff0c;上节课我们通过多个图片直接的切换&#xff0c;今天…

深入理解 RDMA 的软硬件交互机制

作者&#xff1a;羽京 一、前言 随着数据中心的飞速发展&#xff0c;高性能网络不断挑战着带宽与时延的极限&#xff0c;网卡带宽从过去的 10 Gb/s 、25 Gb/s 到如今的 100 Gb/s、200 Gb/s 再到下一代的 400Gb/s 网卡&#xff0c;其发展速度已经远大于 CPU 发展的速度。 为了…