Letbook Cookbook题单——数组2

news2024/9/21 14:50:08

Letbook Cookbook题单——数组2

39. 组合总和

难度中等

给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。

candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。

对于给定的输入,保证和为 target 的不同组合数少于 150 个。

示例 1:

输入:candidates = [2,3,6,7], target = 7
输出:[[2,2,3],[7]]
解释:
2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。
7 也是一个候选, 7 = 7 。
仅有这两种组合。

示例 2:

输入: candidates = [2,3,5], target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]

示例 3:

输入: candidates = [2], target = 1
输出: []

提示:

  • 1 <= candidates.length <= 30
  • 2 <= candidates[i] <= 40
  • candidates 的所有元素 互不相同
  • 1 <= target <= 40

注意每个元素可以重复选取无数次,因此我们多一种递归就行了,第一个直接不选取当前元素从而进入下一个元素的递归,一个选取当前元素后依旧进入当前元素的递归

class Solution {
public:
    void dfs(vector<int>& candidates, int target, vector<vector<int>>& ans, vector<int>& combine, int idx) {
        if (idx == candidates.size()) {
            return;
        }
        if (target == 0) {
            ans.emplace_back(combine);
            return;
        }
        // 直接跳过
        dfs(candidates, target, ans, combine, idx + 1);
        // 选择当前数
        if (target - candidates[idx] >= 0) {
            combine.emplace_back(candidates[idx]);
            dfs(candidates, target - candidates[idx], ans, combine, idx);
            combine.pop_back();
        }
    }

    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> ans;
        vector<int> combine;
        dfs(candidates, target, ans, combine, 0);
        return ans;
    }
};

40. 组合总和 II

难度中等

给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的每个数字在每个组合中只能使用 一次

**注意:**解集不能包含重复的组合。

示例 1:

输入: candidates = [10,1,2,7,6,1,5], target = 8,
输出:
[
[1,1,6],
[1,2,5],
[1,7],
[2,6]
]

示例 2:

输入: candidates = [2,5,2,1,2], target = 5,
输出:
[
[1,2,2],
[5]
]

提示:

  • 1 <= candidates.length <= 100
  • 1 <= candidates[i] <= 50
  • 1 <= target <= 30

排序后去重就很容易了,前面和当前相同就不用选了

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& candidates, int target, int sum, int startIndex, vector<bool>& used) {
        if (sum == target) {
            result.push_back(path);
            return;
        }
        for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) {
            // used[i - 1] == true,说明同一树枝candidates[i - 1]使用过
            // used[i - 1] == false,说明同一树层candidates[i - 1]使用过
            // 要对同一树层使用过的元素进行跳过
            if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) {
                continue;
            }
            sum += candidates[i];
            path.push_back(candidates[i]);
            used[i] = true;
            backtracking(candidates, target, sum, i + 1, used); // 和39.组合总和的区别1,这里是i+1,每个数字在每个组合中只能使用一次
            used[i] = false;
            sum -= candidates[i];
            path.pop_back();
        }
    }

public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        vector<bool> used(candidates.size(), false);
        path.clear();
        result.clear();
        // 首先把给candidates排序,让其相同的元素都挨在一起。
        sort(candidates.begin(), candidates.end());
        backtracking(candidates, target, 0, 0, used);
        return result;
    }
};

41. 缺失的第一个正数

难度困难

给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。

请你实现时间复杂度为

O(n)

并且只使用常数级别额外空间的解决方案。

示例 1:

输入:nums = [1,2,0]
输出:3

示例 2:

输入:nums = [3,4,-1,1]
输出:2

示例 3:

输入:nums = [7,8,9,11,12]
输出:1

提示:

  • 1 <= nums.length <= 5 * 105
  • -231 <= nums[i] <= 231 - 1

有意思的题,原地哈希

官方题解讲得挺好的,就不自己多加阐述

在这里插入图片描述

42. 接雨水

难度困难

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

示例 1:

img

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

比较恶心的一道题,还只过了一种写法,双指针和栈写法暂时还没写

参考这个大佬的写法

在这里插入图片描述

按行求解(超时)

整个思路就是,求第 i 层的水,遍历每个位置,如果当前的高度小于 i,并且两边有高度大于等于 i 的,说明这个地方一定有水,水就可以加 1。

如果求高度为 i 的水,首先用一个变量 temp 保存当前累积的水,初始化为 0。从左到右遍历墙的高度,遇到高度大于等于 i 的时候,开始更新 temp。更新原则是遇到高度小于 i 的就把 temp 加 1,遇到高度大于等于 i 的,就把 temp 加到最终的答案 ans 里,并且 temp 置零,然后继续循环。

我们就以题目的例子讲一下。

先求第 11 行的水。

image.png

也就是红色区域中的水,数组是 height = [ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 ] 。

原则是高度小于 1,temp ++,高度大于等于 1,ans = ans + temp,temp = 0。

temp 初始化为 0,ans = 0

height[0] 等于 0 < 1,不更新。

height[1] 等于 1 >= 1,开始更新 temp。

height[2] 等于 0 < 1,temp = temp + 1 = 1。

height[3] 等于 2 >= 1,ans = ans + temp = 1,temp = 0。

height[4] 等于 1 >= 1,ans = ans + temp = 1,temp = 0。

height[5] 等于 0 < 1,temp = temp + 1 = 1。

height[6] 等于 1 >= 1,ans = ans + temp = 2,temp = 0。

剩下的 height[7] 到最后,高度都大于等于 1,更新 ans = ans + temp = 2,temp = 0。而其实 temp 一直都是 0,所以 ans 没有变化。

再求第 2 行的水。

image.png

也就是红色区域中的水,数组是 height = [ 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 ]。

原则是高度小于 2,temp ++,高度大于等于 2,ans = ans + temp,temp = 0。

temp 初始化为 0,ans 此时等于 2。

height[0] 等于 0 < 2,不更新。

height[1] 等于 1 < 2,不更新。

height[2] 等于 0 < 2,不更新。

height[3] 等于 2 >= 2,开始更新

height[4] 等于 1 < 2,temp = temp + 1 = 1。

height[5] 等于 0 < 2,temp = temp + 1 = 2。

height[6] 等于 1 < 2,temp = temp + 1 = 3。

height[7] 等于 3 >= 2,ans = ans + temp = 5,temp = 0。

height[8] 等于 2 >= 2,ans = ans + temp = 3,temp = 0。

height[9] 等于 1 < 2,temp = temp + 1 = 1。

height[10] 等于 2 >= 2,ans = ans + temp = 6,temp = 0。

height[11] 等于 1 < 2,temp = temp + 1 = 1。

然后结束循环,此时的 ans 就是6。

再看第 3 层。

image.png

按照之前的算法,之前的都是小于 3 的,不更新 temp,然后到 height[7] 等于 3,开始更新 temp,但是后边没有 height 大于等于 3 了,所以 ans 没有更新。

所以最终的 ans 就是 6。

思路很清楚,就是h[i]的最大有点大,所以会超时

class Solution {
public:
int trap(vector<int>&height) {
    int sum = 0;
    int max = getMax(height);//找到最大的高度,以便遍历。
    for (int i = 1; i <= max; i++) {
        bool isStart = false; //标记是否开始更新 temp
        int temp_sum = 0;
        for (int j = 0; j < height.size(); j++) {
            if (isStart && height[j] < i) {
                temp_sum++;
            }
            if (height[j] >= i) {
                sum = sum + temp_sum;
                temp_sum = 0;
                isStart = true;
            }
        }
    }
    return sum;
}
int getMax(vector<int>& height) {
		int max = 0;
		for (int i = 0; i < height.size(); i++) {
			if (height[i] > max) {
				max = height[i];
			}
		}
		return max;
}
};

按列求解(优化后不会超时)

求每一列的水,我们只需要关注当前列,以及左边最高的墙,右边最高的墙就够了。

装水的多少,当然根据木桶效应,我们只需要看左边最高的墙和右边最高的墙中较矮的一个就够了。

所以,根据较矮的那个墙和当前列的墙的高度可以分为三种情况。

较矮的墙的高度大于当前列的墙的高度

image.png

把正在求的列左边最高的墙和右边最高的墙确定后,然后为了方便理解,我们把无关的墙去掉。

image.png

这样就很清楚了,现在想象一下,往两边最高的墙之间注水。正在求的列会有多少水?

很明显,较矮的一边,也就是左边的墙的高度,减去当前列的高度就可以了,也就是 2 - 1 = 1,可以存一个单位的水。

较矮的墙的高度小于当前列的墙的高度

image.png

同样的,我们把其他无关的列去掉。

image.png

想象下,往两边最高的墙之间注水。正在求的列会有多少水?

正在求的列不会有水,因为它大于了两边较矮的墙。

较矮的墙的高度等于当前列的墙的高度。

和上一种情况是一样的,不会有水。

image.png

明白了这三种情况,程序就很好写了,遍历每一列,然后分别求出这一列两边最高的墙。找出较矮的一端,和当前列的高度比较,结果就是上边的三种情况。

这份代码比上面那个好点,但是会在最后一个恶心数据上过不去

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IHVWkUW7-1670348541360)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\1670348284997.png)]

class Solution {
public:
   int trap(vector<int>& height) {
    int sum = 0;
    //最两端的列不用考虑,因为一定不会有水。所以下标从 1 到 length - 2
    for (int i = 1; i < height.size() - 1; i++) {
        int max_left = 0;
        //找出左边最高
        for (int j = i - 1; j >= 0; j--) {
            if (height[j] > max_left) {
                max_left = height[j];
            }
        }
        int max_right = 0;
        //找出右边最高
        for (int j = i + 1; j < height.size(); j++) {
            if (height[j] > max_right) {
                max_right = height[j];
            }
        }
        //找出两端较小的
        int minx = min(max_left, max_right);
        //只有较小的一段大于当前列的高度才会有水,其他情况不会有水
        if (minx > height[i]) {
            sum = sum + (minx - height[i]);
        }
    }
    return sum;
}

};

因此我们需要优化下,注意我们当前位置左边最大后右边最大可以由当前位置的前面一个位置的左右最大值得出

class Solution {
public:
    int trap(vector<int>& h) {
        int l, r, maxl = 0, maxr = 1e6, ans = 0, num = 0;
        for (int i = 1; i < h.size() - 1; i++)
        {
            if (maxl <= h[i - 1])
                maxl = h[i - 1];
            if (h[i] == maxr)
                num--;
                if (num == 0||i==1)
                {
                    maxr = 0;
                    r = i + 1;
                    while (r < h.size())
                    {
                        if (h[r] > maxr)
                            maxr = h[r], num = 1;
                        else if (h[r] == maxr)
                            num++;
                        r++;
                    }
                }
            if (min(maxl, maxr) > h[i])
                ans += min(maxl, maxr) - h[i];
        }
        return ans;
    }
};

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

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

相关文章

Qgis加载arcgis的gdb格式数据

方式1&#xff1a;文件浏览器打开可直接看到图层&#xff0c;拖到可视区域即可。 方式2&#xff1a;gdb文件夹拖到可视区域即可。 方式3&#xff1a;图层-矢量-目录 该gdb可能没有坐标信息&#xff0c;需要跟甲方询问或者自己尝试

安卓APP源码和设计报告——快递查询录入系统

《多媒体通信技术》 题 目&#xff1a;快递 完 成 日 期 2022年05月 目 录 1 绪论1 2 设计方案2 2.1 设计思路和方案2 2.2 功能要求2 2.3 设计的流程图2 3 设计过程3 3.1 界面布局3 3.2 功能实现3 4 运行结果与分析4 4.1 设计的使用步骤4 4.2 运行结果与分析4 5 …

【数据结构】—带头双向循环链表的实现(完美链表)

目录前言链表的实现新节点的创建链表初始化尾插与尾删头插与头删查找数据在任意位置的插入与删除链表的销毁总结前言 链表结构一共有八种形式&#xff0c;在前面的文章里已经讲完了不带头单向非循环链表的实现&#xff0c;但是我们发现该链表实现尾插与尾删时比较麻烦&#xff…

Java学习多态之向上转型

目录 一、向上转型的本质 举例说明 父类-Animal 子类-Cat类 测试-PolyDetail 语法 Object类 二、向上转型的特点 第一条 第二条 第三条 例子 Base类 TopBase类 测试类 第四条 运行结果 多态的前提&#xff1a;两个对象&#xff08;类&#xff09;存在继承关系 …

【软件测试】测试新人咋迅速成为bug小能手?刮目相看......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 对于很多新入行测试…

Linux学习笔记

IO操作 概述 根据用户态和内核态的划分&#xff0c;用户态的进程是不能直接访问各种硬件资源的&#xff0c;只能向内核发起系统调用&#xff0c;由内核完成一系列操作再切回用户进程。 用户进程每次想要访问硬件资源&#xff08;包括读和写&#xff09;就叫做一次IO。 IO共有…

梦开始的地方——C语言文件操作详解

文章目录C语言文件操作1. 什么是文件&#xff1f;2.文件指针3.文件的打开和关闭4.文件的顺序读写fgetc&fputcfgets&fputsfread&fwritefscanf&fprintfscanf/fscanf/sscanf 对比 printf/fprintf/sprintf5.文件的随机读写(fseek&ftell &rewind)6. 文件结束…

兄弟机床联网

一、设备信息确认 1、确认型号 看面板颜色&#xff1a; 面板如果是彩色屏幕&#xff0c;大概率是可以做联网采集的。如果是黑白屏则需要进一步确认设备名牌。 看名牌&#xff1a; 名牌一般在设备后面&#xff0c;可以看到数控系统的品牌&#xff0c;一般C00和B00都是可以直接…

怎么写综述类论文? - 易智编译EaseEditing

一、确定综述的主题 每篇综述都应该有一个观点&#xff0c;即想要表达的事物。一篇综述不是简单的对相关发现的罗列。综述的真正功能是迈出下一步。已有的研究告诉了我们什么&#xff1f;以及我们下一步要怎么做&#xff1f; 确定综述的主题在撰写过程中是最重要的一步。这会…

快速上手几个Linux命令

Linux操作系统有很多功能&#xff0c;我们有很多方式可以使用这些功能&#xff0c;其中最简单和直接的方式就是命令行&#xff08;Command Line&#xff09; 用户与密码 当我们打开一个新系统的时候&#xff0c;第一件要做的事就是登录。系统默认有一个 Administrator 用户&a…

Vue学习:Vue中的数据代理

<!-- 准备容器 --><div idroot> <h2>学校名称&#xff1a;{{name}}</h2><h2>学校地址&#xff1a;{{adress}}</h2></div><script>const vm new Vue({ el: #root,data: {name:Jhon,adress:street 10},});</script> vm上…

8.javase_数组2

一 . 二维数组 (1)二维数组 元素为一维数组的数组 (2)定义格式&#xff1a; 数据类型[][] 变量名; int[][] arr; 数据类型 变量名[][]; int arr[][]; 数据类型[] 变量名[]; int[] arr[]; 二.二维数组初始化 (1)静态初始化 格式&#xff1a;数据类型[][] 变量名 new 数据类型…

PNG怎么转成PDF格式?这两种方法一定要尝试一下

图片文件是我们经常使用到的一种文件类型&#xff0c;但是我们通常会有很多的图片需要同时进行发送&#xff0c;这时候发送给别人就不是很便利了&#xff0c;我们一般会需要通过微信进行发送&#xff0c;但是大家都知道&#xff0c;微信一次只能发送九张图片&#xff0c;有时候…

【CDC跨时钟域信号处理】快时钟域到慢时钟域-单bit

快时钟域到慢时钟域分两种情况&#xff1a; 1、允许采样丢失&#xff1a;直接采用同步器即可。 2、不允许采样丢失&#xff1a;原理是保证快时钟域的信号宽度满足一定的条件&#xff0c;使得慢时钟域有足够的时间采样到。 对于情况2有两种方法解决&#xff1a;①信号展宽边沿检…

接口管理测试繁琐复杂?何不试试Eolink

一、前言 作为一名测试从业者&#xff0c;深刻的明白接口测试在项目过程中是多么重要的一个环节。通过页面进行的UI测试会因为界面不稳定而导致用例维护非常困难。另外&#xff0c;在检查系统的安全性、稳定性上面也是尤为重要的环节&#xff0c;这些也是无法通过前端测试的&a…

react-native webstorm 无法启动 Android 模拟器

react-native webstorm 无法启动 Android 模拟器 一、问题描述 在 安装完 Android Studio 和 模拟器之后&#xff0c;WebStorm 启动 react-native 项目时提示如下&#xff1a; No emulators found as an output of emulator -list-avds.二、解决办法 官方环境安装说明&#x…

汽车OTA技术门槛提升,具备软硬一体化能力的Tier1优势凸显

在软件定义汽车的大背景下&#xff0c;无论是传统车企还是造车新势力都在加大OTA的布局力度&#xff0c;整车OTA的普及应用已经成为必然趋势。 高工智能汽车研究院监测数据显示&#xff0c;2022年1-6月中国市场&#xff08;不含进出口&#xff09;乘用车标配搭载OTA上险量为40…

移动硬盘raw怎么办?一招教你解决RAW格式的文件

RAW文件格式是一种特殊的文件格式。RAW表示未处理&#xff0c;因此RAW也指未格式化的磁盘。移动硬盘里有 RAW格式的文件。这是什么原因造成的&#xff1f;以及我们该如何把移动硬盘raw里面的文件给恢复回来&#xff1f;来看看下面的解说&#xff0c;一起寻找解决方法吧&#xf…

阿里云国际站云计算-负载均衡SLB介绍-unirech

阿里云国际站的负载均衡SLB&#xff08;Server Load Balancer&#xff09;是一种对流量进行按需分发的服务&#xff0c;通过将流量分发到不同的后端服务器来扩展应用系统的吞吐能力&#xff0c;并且可以消除系统中的单点故障&#xff0c;提升应用系统的可用性。 阿里云国际站的…