【题解】—— LeetCode一周小结44

🌟欢迎来到 我的博客 —— 探索技术的无限可能!


🌟博客的简介(文章目录)


【题解】—— 每日一道题目栏


上接:【题解】—— LeetCode一周小结43

28.冗余连接 II

题目链接:685. 冗余连接 II

在本问题中,有根树指满足以下条件的 有向 图。该树只有一个根节点,所有其他节点都是该根节点的后继。该树除了根节点之外的每一个节点都有且只有一个父节点,而根节点没有父节点。

输入一个有向图,该图由一个有着 n 个节点(节点值不重复,从 1 到 n)的树及一条附加的有向边构成。附加的边包含在 1 到 n 中的两个不同顶点间,这条附加的边不属于树中已存在的边。

结果图是一个以边组成的二维数组 edges 。 每个元素是一对 [ui, vi],用以表示 有向 图中连接顶点 ui 和顶点 vi 的边,其中 ui 是 vi 的一个父节点。

返回一条能删除的边,使得剩下的图是有 n 个节点的有根树。若有多个答案,返回最后出现在给定二维数组的答案。

示例 1:

在这里插入图片描述

输入:edges = [[1,2],[1,3],[2,3]]

输出:[2,3]

示例 2:

在这里插入图片描述

输入:edges = [[1,2],[2,3],[3,4],[4,1],[1,5]]

输出:[4,1]

提示:

n == edges.length

3 <= n <= 1000

edges[i].length == 2

1 <= ui, vi <= n

题解:
方法:并查集
        

class Solution {
    private int[] p;

    public int[] findRedundantDirectedConnection(int[][] edges) {
        int n = edges.length;
        int[] ind = new int[n];
        for (var e : edges) {
            ++ind[e[1] - 1];
        }
        List<Integer> dup = new ArrayList<>();
        p = new int[n];
        for (int i = 0; i < n; ++i) {
            if (ind[edges[i][1] - 1] == 2) {
                dup.add(i);
            }
            p[i] = i;
        }
        if (!dup.isEmpty()) {
            for (int i = 0; i < n; ++i) {
                if (i == dup.get(1)) {
                    continue;
                }
                int pu = find(edges[i][0] - 1);
                int pv = find(edges[i][1] - 1);
                if (pu == pv) {
                    return edges[dup.get(0)];
                }
                p[pu] = pv;
            }
            return edges[dup.get(1)];
        }
        for (int i = 0;; ++i) {
            int pu = find(edges[i][0] - 1);
            int pv = find(edges[i][1] - 1);
            if (pu == pv) {
                return edges[i];
            }
            p[pu] = pv;
        }
    }

    private int find(int x) {
        if (p[x] != x) {
            p[x] = find(p[x]);
        }
        return p[x];
    }
}

29.生成不含相邻零的二进制字符串

题目链接:3211. 生成不含相邻零的二进制字符串

给你一个正整数 n。

如果一个二进制字符串 x 的所有长度为 2 的
子字符串
中包含 至少 一个 “1”,则称 x 是一个 有效 字符串。

返回所有长度为 n 的 有效 字符串,可以以任意顺序排列。

示例 1:

输入: n = 3

输出: [“010”,“011”,“101”,“110”,“111”]

解释:

长度为 3 的有效字符串有:“010”、“011”、“101”、“110” 和 “111”。

示例 2:

输入: n = 1

输出: [“0”,“1”]

解释:

长度为 1 的有效字符串有:“0” 和 “1”。

提示:

1 <= n <= 18

题解:
方法:回溯(爆搜)
        

class Solution {
    public List<String> validStrings(int n) {
        List<String> ans = new ArrayList<>();
        char[] path = new char[n];
        dfs(0, n, path, ans);
        return ans;
    }

    private void dfs(int i, int n, char[] path, List<String> ans) {
        if (i == n) {
            ans.add(new String(path));
            return;
        }

        // 填 1
        path[i] = '1';
        dfs(i + 1, n, path, ans);

        // 填 0
        if (i == 0 || path[i - 1] == '1') {
            path[i] = '0'; // 直接覆盖
            dfs(i + 1, n, path, ans);
        }
    }
}

30.交换后字典序最小的字符串

题目链接:3216. 交换后字典序最小的字符串

给你一个仅由数字组成的字符串 s,在最多交换一次 相邻 且具有相同 奇偶性 的数字后,返回可以得到的
字典序最小的字符串

如果两个数字都是奇数或都是偶数,则它们具有相同的奇偶性。例如,5 和 9、2 和 4 奇偶性相同,而 6 和 9 奇偶性不同。

示例 1:

输入: s = “45320”

输出: “43520”

解释:

s[1] == ‘5’ 和 s[2] == ‘3’ 都具有相同的奇偶性,交换它们可以得到字典序最小的字符串。

示例 2:

输入: s = “001”

输出: “001”

解释:

无需进行交换,因为 s 已经是字典序最小的。

提示:

2 <= s.length <= 100

s 仅由数字组成。

题解:
方法:贪心
        

class Solution {
    public String getSmallestString(String s) {
        char[] t = s.toCharArray();
        for (int i = 1; i < t.length; i++) {
            char x = t[i - 1];
            char y = t[i];
            if (x > y && x % 2 == y % 2) {
                t[i - 1] = y;
                t[i] = x;
                break;
            }
        }
        return new String(t);
    }
}

31.不包含相邻元素的子序列的最大和

题目链接:3165. 不包含相邻元素的子序列的最大和

给你一个整数数组 nums 和一个二维数组 queries,其中 queries[i] = [posi, xi]。

对于每个查询 i,首先将 nums[posi] 设置为 xi,然后计算查询 i 的答案,该答案为 nums 中 不包含相邻元素 的
子序列
的 最大 和。

返回所有查询的答案之和。

由于最终答案可能非常大,返回其对 109 + 7 取余 的结果。

子序列 是指从另一个数组中删除一些或不删除元素而不改变剩余元素顺序得到的数组。

示例 1:

输入:nums = [3,5,9], queries = [[1,-2],[0,-3]]

输出:21

解释:

执行第 1 个查询后,nums = [3,-2,9],不包含相邻元素的子序列的最大和为 3 + 9 = 12。

执行第 2 个查询后,nums = [-3,-2,9],不包含相邻元素的子序列的最大和为 9 。

示例 2:

输入:nums = [0,-1], queries = [[0,-5]]

输出:0

解释: 执行第 1 个查询后,nums = [-5,-1],不包含相邻元素的子序列的最大和为 0(选择空子序列)。

提示:

1 <= nums.length <= 5 * 104

-105 <= nums[i] <= 105

1 <= queries.length <= 5 * 104

queries[i] == [posi, xi]

0 <= posi <= nums.length - 1

-105 <= xi <= 105

题解:
方法:分治思想+线段树
        

class Solution {
    public int maximumSumSubsequence(int[] nums, int[][] queries) {
        int n = nums.length;
        // 4 个数分别保存 f00, f01, f10, f11
        long[][] t = new long[2 << (32 - Integer.numberOfLeadingZeros(n))][4];
        build(t, nums, 1, 0, n - 1);

        long ans = 0;
        for (int[] q : queries) {
            update(t, 1, 0, n - 1, q[0], q[1]);
            ans += t[1][3]; // 注意 f11 没有任何限制,也就是整个数组的打家劫舍
        }
        return (int) (ans % 1_000_000_007);
    }

    // 合并左右儿子
    private void maintain(long[][] t, int o) {
        long[] a = t[o * 2];
        long[] b = t[o * 2 + 1];
        t[o][0] = Math.max(a[0] + b[2], a[1] + b[0]);
        t[o][1] = Math.max(a[0] + b[3], a[1] + b[1]);
        t[o][2] = Math.max(a[2] + b[2], a[3] + b[0]);
        t[o][3] = Math.max(a[2] + b[3], a[3] + b[1]);
    }

    // 用 nums 初始化线段树
    private void build(long[][] t, int[] nums, int o, int l, int r) {
        if (l == r) {
            t[o][3] = Math.max(nums[l], 0);
            return;
        }
        int m = (l + r) / 2;
        build(t, nums, o * 2, l, m);
        build(t, nums, o * 2 + 1, m + 1, r);
        maintain(t, o);
    }

    // 把 nums[i] 改成 val
    private void update(long[][] t, int o, int l, int r, int i, int val) {
        if (l == r) {
            t[o][3] = Math.max(val, 0);
            return;
        }
        int m = (l + r) / 2;
        if (i <= m) {
            update(t, o * 2, l, m, i, val);
        } else {
            update(t, o * 2 + 1, m + 1, r, i, val);
        }
        maintain(t, o);
    }
}


2024.11

1.超级饮料的最大强化能量

题目链接:3259. 超级饮料的最大强化能量

来自未来的体育科学家给你两个整数数组 energyDrinkA 和 energyDrinkB,数组长度都等于 n。这两个数组分别代表 A、B 两种不同能量饮料每小时所能提供的强化能量。

你需要每小时饮用一种能量饮料来 最大化 你的总强化能量。然而,如果从一种能量饮料切换到另一种,你需要等待一小时来梳理身体的能量体系(在那个小时里你将不会获得任何强化能量)。

返回在接下来的 n 小时内你能获得的 最大 总强化能量。

注意 你可以选择从饮用任意一种能量饮料开始。

示例 1:

输入:energyDrinkA = [1,3,1], energyDrinkB = [3,1,1]

输出:5

解释:

要想获得 5 点强化能量,需要选择只饮用能量饮料 A(或者只饮用 B)。

示例 2:

输入:energyDrinkA = [4,1,1], energyDrinkB = [1,1,3]

输出:7

解释:

第一个小时饮用能量饮料 A。

切换到能量饮料 B ,在第二个小时无法获得强化能量。

第三个小时饮用能量饮料 B ,并获得强化能量。

提示:

n == energyDrinkA.length == energyDrinkB.length

3 <= n <= 105

1 <= energyDrinkA[i], energyDrinkB[i] <= 105

题解:
方法:递归搜索 + 保存递归返回值 = 记忆化搜索
        

class Solution {
    public long maxEnergyBoost(int[] a, int[] b) {
        int n = a.length;
        int[][] c = {a, b};
        long[][] memo = new long[n][2];
        return Math.max(dfs(n - 1, 0, c, memo), dfs(n - 1, 1, c, memo));
    }

    private long dfs(int i, int j, int[][] c, long[][] memo) {
        if (i < 0) {
            return 0;
        }
        if (memo[i][j] > 0) { // 之前计算过
            return memo[i][j];
        }
        return memo[i][j] = Math.max(dfs(i - 1, j, c, memo), dfs(i - 2, j ^ 1, c, memo)) + c[j][i];
    }
}

2.使两个整数相等的位更改次数

题目链接:3226. 使两个整数相等的位更改次数

给你两个正整数 n 和 k。

你可以选择 n 的 二进制表示 中任意一个值为 1 的位,并将其改为 0。

返回使得 n 等于 k 所需要的更改次数。如果无法实现,返回 -1。

示例 1:

输入: n = 13, k = 4

输出: 2

解释: 最初,n 和 k 的二进制表示分别为 n = (1101)2 和 k = (0100)2,

我们可以改变 n 的第一位和第四位。结果整数为 n = (0100)2 = k。

示例 2:

输入: n = 21, k = 21

输出: 0

解释: n 和 k 已经相等,因此不需要更改。

示例 3:

输入: n = 14, k = 13

输出: -1

解释: 无法使 n 等于 k。

提示:

1 <= n, k <= 106

题解:
方法:O(1) 位运算做法
        

class Solution {
    public int minChanges(int n, int k) {
        return (n & k) != k ? -1 : Integer.bitCount(n ^ k);
    }
}

3.大礼包

题目链接:638. 大礼包

在 LeetCode 商店中, 有 n 件在售的物品。每件物品都有对应的价格。然而,也有一些大礼包,每个大礼包以优惠的价格捆绑销售一组物品。

给你一个整数数组 price 表示物品价格,其中 price[i] 是第 i 件物品的价格。另有一个整数数组 needs 表示购物清单,其中 needs[i] 是需要购买第 i 件物品的数量。

还有一个数组 special 表示大礼包,special[i] 的长度为 n + 1 ,其中 special[i][j] 表示第 i 个大礼包中内含第 j 件物品的数量,且 special[i][n] (也就是数组中的最后一个整数)为第 i 个大礼包的价格。

返回 确切 满足购物清单所需花费的最低价格,你可以充分利用大礼包的优惠活动。你不能购买超出购物清单指定数量的物品,即使那样会降低整体价格。任意大礼包可无限次购买。

示例 1:

输入:price = [2,5], special = [[3,0,5],[1,2,10]], needs = [3,2]

输出:14

解释:有 A 和 B 两种物品,价格分别为 ¥2 和 ¥5 。

大礼包 1 ,你可以以 ¥5 的价格购买 3A 和 0B 。

大礼包 2 ,你可以以 ¥10 的价格购买 1A 和 2B 。

需要购买 3 个 A 和 2 个 B , 所以付 ¥10 购买 1A 和 2B(大礼包 2),以及 ¥4 购买 2A 。

示例 2:

输入:price = [2,3,4], special = [[1,1,0,4],[2,2,1,9]], needs = [1,2,1]

输出:11

解释:A ,B ,C 的价格分别为 ¥2 ,¥3 ,¥4 。

可以用 ¥4 购买 1A 和 1B ,也可以用 ¥9 购买 2A ,2B 和 1C 。

需要买 1A ,2B 和 1C ,所以付 ¥4 买 1A 和 1B(大礼包 1),以及 ¥3 购买 1B , ¥4 购买 1C 。

不可以购买超出待购清单的物品,尽管购买大礼包 2 更加便宜。

提示:

n == price.length == needs.length

1 <= n <= 6

0 <= price[i], needs[i] <= 10

1 <= special.length <= 100

special[i].length == n + 1

0 <= special[i][j] <= 50

生成的输入对于 0 <= j <= n - 1 至少有一个 special[i][j] 非零。

题解:
方法:状态压缩 + 记忆化搜索
        

class Solution {
    private final int bits = 4;
    private int n;
    private List<Integer> price;
    private List<List<Integer>> special;
    private Map<Integer, Integer> f = new HashMap<>();

    public int shoppingOffers(
        List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
        n = needs.size();
        this.price = price;
        this.special = special;
        int mask = 0;
        for (int i = 0; i < n; ++i) {
            mask |= needs.get(i) << (i * bits);
        }
        return dfs(mask);
    }

    private int dfs(int cur) {
        if (f.containsKey(cur)) {
            return f.get(cur);
        }
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans += price.get(i) * (cur >> (i * bits) & 0xf);
        }
        for (List<Integer> offer : special) {
            int nxt = cur;
            boolean ok = true;
            for (int j = 0; j < n; ++j) {
                if ((cur >> (j * bits) & 0xf) < offer.get(j)) {
                    ok = false;
                    break;
                }
                nxt -= offer.get(j) << (j * bits);
            }
            if (ok) {
                ans = Math.min(ans, offer.get(n) + dfs(nxt));
            }
        }
        f.put(cur, ans);
        return ans;
    }
}

下接:【题解】—— LeetCode一周小结45


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

视频Qoe测量学习笔记(一)

目录 流媒体协议详解 RTSP&#xff1a;实时流式协议 RTCP&#xff1a;实时运输控制协议 RTP&#xff1a;实时运输协议 H.264 流媒体协议详解 RTSP&#xff1a;实时流式协议 由IETF MMusic小组开发&#xff0c;已成为互联网建议标准[RFC 2326]。RTSP本身并不传送数据&…

使用Spring Validation实现数据校验详解

目录 前言1. Spring Validation概述2. 配置Spring Validation2.1 引入依赖2.2 启用全局校验 3. 使用注解进行参数校验3.1 基本校验注解3.2 使用Pattern进行正则校验3.3 综合示例 4. 在控制器层应用校验4.1 方法参数校验4.2 自定义错误处理 5. 高级应用&#xff1a;自定义校验注…

解决阿里云三个月证书过期 免费SSL证书部署教程

相信有上线过自己的网站、小程序经验的同学深有体会&#xff0c;给服务加上 SSL 证书还挺麻烦的&#xff0c;尤其是没有运维经验的同学。本来最省事的方法是买个证书&#xff0c;但是一看价格&#xff0c;还是算了吧&#xff0c;动辄就是几万块一年。作为个人来说&#xff0c;这…

简单走近ChatGPT

目录 一、ChatGPT整体背景认知 &#xff08;一&#xff09;ChatGPT引起关注的原因 &#xff08;二&#xff09;与其他公司的竞争情况 二、NLP学习范式的发展 &#xff08;一&#xff09;规则和机器学习时期 &#xff08;二&#xff09;基于神经网络的监督学习时期 &…

恢复Ubuntu+Windows10双系统安装前状态及分区还原详细步骤

1、恢复到安装 Ubuntu 之前的状态&#xff0c;先看看系统属性 2、选择 运行 3、 输入 msinfo32 回车 4、注意查看 BIOS 模式这一栏&#xff0c;UEFI&#xff0c;这里我们以UEFI系统为例 5、下来就可以开始进行 Ubuntu 的移除操作了 6、从Windows打开网页搜索磁盘精灵&#xff0…

一文搞定 InternStudio 开发机的使用 | 书生大模型

文章目录 创建开发机使用 SSH 远程连接开发机使用密码进行 SSH 远程连接使用 VScode 进行 SSH 远程连接 端口映射核心目标开发机端口映射的工作方式使用 VScode 进行端口映射运行 hello_world.py 代码进行测试测试成功页面 参考文献 创建开发机 InternStudio控制台 这里先做测…

WindowsDocker安装到D盘,C盘太占用空间了。

Windows安装 Docker Desktop的时候,默认位置是安装在C盘,使用Docker下载的镜像文件也是保存在C盘,如果对Docker使用评率比较高的小伙伴,可能C盘空间,会被耗尽,有没有一种办法可以将Docker安装到其它磁盘,同时Docker的数据文件也保存在其他磁盘呢? 答案是有的,我们可以…

关于我、重生到500年前凭借C语言改变世界科技vlog.15——深入理解指针(4)

文章目录 1.回调函数的介绍2. qsort使用实例2.1 qsort函数介绍2.2使用 qsort 函数排序整型数据2.3使用 qsort 排序结构数据 3. qsort的模拟实现希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力&#xff01; 1.回调函数的介绍 回调函数就是一个通过函数指针调用…

内网项目,maven本地仓库离线打包,解决Cannot access central in offline mode?

背景&#xff1a; 内网项目打包&#xff0c;解决Cannot access central in offline mode? 1、修改maven配置文件&#xff1a; localRepository改为本地仓库位置 <localRepository>D:\WorkSpace\WorkSoft\maven-repository\iwhalecloud-repository\business</loca…

笔记整理—linux驱动开发部分(8)framebuffer类设备

framebuffer显示设备。 在应用层直接抽象位向DDR中存放图片。 在操作系统中&#xff0c;将上图分为两个部分&#xff1a;驱动应用。 使用复制的方法效率十分的低&#xff0c;所以有了内存映射方法实现图片的显示。 framebuffer帧&#xff08;铺满一个屏幕&#xff09;&#xff…

第三十章 章节练习商品列表组件封装

目录 一、需求说明 二、技术要点 三、完整代码 3.1. main.js 3.2. App.vue 3.3. MyTable.vue 3.4. MyTag.vue 一、需求说明 1. my-tag 标签组件封装 (1) 双击显示输入框&#xff0c;输入框获取焦点 (2) 失去焦点&#xff0c;隐藏输入框 (3) 回显标签信息 (4) 内…

EHOME视频平台EasyCVR萤石设备视频接入平台视频诊断技术可以识别哪些视频质量问题?

EasyCVR视频监控汇聚管理平台是一款针对大中型项目设计的跨区域网络化视频监控集中管理平台。萤石设备视频接入平台EasyCVR不仅具备视频资源管理、设备管理、用户管理、运维管理和安全管理等功能&#xff0c;还支持多种主流标准协议&#xff0c;如GB28181、GB35114、RTSP/Onvif…

如何在 PyQt 中启动“绘图循环”?

在 PyQt 中实现一个“绘图循环”可以使用 定时器&#xff08;QTimer&#xff09;&#xff0c;让应用程序在指定的时间间隔内反复触发一个绘图函数。这种方法对于需要持续更新绘图&#xff08;例如动画效果&#xff09;的情况特别有用。 1、问题背景 在GUI编程中&#xff0c;我…

Linux 线程控制

一. 线程互斥 1.1 线程互斥相关概念 临界资源&#xff1a;多线程执行流共享的资源就叫做临界资源。临界区&#xff1a;每个线程内部&#xff0c;访问临界资源的代码&#xff0c;就叫做临界区。互斥&#xff1a;任何时刻&#xff0c;互斥保证有且只有一个执行流进入临界区&…

分布式光伏发电的投融资计算

分布式光伏发电项目的成功实施离不开科学、合理的投融资计算&#xff0c;为光伏项目的前期开发提供切实可行的依据。 一、分布式光伏发电项目的投资成本 分布式光伏发电项目的投资成本包括多个方面&#xff0c;主要包括光伏组件采购成本、逆变器和支架系统成本、安装和施工成本…

MyBatis 返回 Map 或 List<Map>时,时间类型数据,默认为LocalDateTime,响应给前端默认含有‘T‘字符

一、问题 MyBatis 返回 Map 或 List时&#xff0c;时间类型数据&#xff0c;默认为LocalDateTime Springboot 响应给前端的LocalDateTime&#xff0c;默认含有’T’字符&#xff0c;如何统一配置去掉 二、解决方案 1、pom.xml 增加依赖&#xff08;2024.11.6 补充&#xff…

AMD显卡低负载看视频掉驱动(chrome edge浏览器) 高负载玩游戏却稳定 解决方法——关闭MPO

问题 折磨的开始是天下苦黄狗久矣&#xff0c;为了不再被讨乞丐的显存恶心&#xff0c;一怒之下购入了AMD显卡&#xff08;20GB显存确实爽 头一天就跑了3dmark验机&#xff0c;完美通过&#xff0c;玩游戏也没毛病 但是呢这厮是一点不省心&#xff0c;玩游戏没问题&#xff0c…

记录新建wordpress站的实践踩坑:wordpress 上传源码新建站因权限问题导致无法访问、配置新站建站向导以及插件主题上传配置的解决办法

官方文档&#xff1a;How to install WordPress – Advanced Administration Handbook | Developer.WordPress.org 但是没写权限问题&#xff0c;可以下载到 wordpress官方包。 把下载的wordpresscn的包解压并上传到服务器目录下&#xff0c;但是因为是root上传导致了权限问题…

【大数据学习 | kafka】kafka的偏移量管理

1. 偏移量的概念 消费者在消费数据的时候需要将消费的记录存储到一个位置&#xff0c;防止因为消费者程序宕机而引起断点消费数据丢失问题&#xff0c;下一次可以按照相应的位置从kafka中找寻数据&#xff0c;这个消费位置记录称之为偏移量offset。 kafka0.9以前版本将偏移量信…

迪杰斯特拉算法

迪杰斯特拉算法 LeetCode 743. 网络延迟时间 https://blog.csdn.net/xiaoxi_hahaha/article/details/110257368 import sysdef dijkstra(graph, source):"""dijkstra算法:param graph: 邻接矩阵:param source: 出发点&#xff0c;源点:return:""&…