LeetCode第16~20题解

news/2024/7/20 21:20:09 标签: leetcode, 深度优先, 算法, c++, python

CONTENTS

    • LeetCode 16. 最接近的三数之和(中等)
    • LeetCode 17. 电话号码的字母组合(中等)
    • LeetCode 18. 四数之和(中等)

LeetCode 16. 最接近的三数之和(中等)

【题目描述】

给你一个长度为 n 的整数数组 nums 和一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。

【示例1】

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

【示例2】

输入:nums = [0,0,0], target = 1
输出:0

【提示】

3 ≤ n u m s . l e n g t h ≤ 1000 3\le nums.length\le 1000 3nums.length1000
− 1000 ≤ n u m s [ i ] ≤ 1000 -1000\le nums[i]\le 1000 1000nums[i]1000
− 1 0 4 ≤ t a r g e t ≤ 1 0 4 -10^4\le target\le 10^4 104target104

【分析】


和第15题相似,和 target 最接近的数可能是大于等于 target 的最小的数,也可能是小于等于 target 的最大的数。前者和第15题一样,枚举指针 i i i,然后用双指针 j j j k k k 求出大于等于 target 的最小的数。由于我们之前的实现方式是将 k k k 从右向左移动,找到 nums[i] + nums[j] + nums[k] >= target最小 k k k,因此我们可以得出 nums[i] + nums[j] + nums[k - 1] < target k − 1 k-1 k1 是满足该式的最大 k k k(需要注意保证 k − 1 ≠ j k-1\ne j k1=j)。


【代码】

class Solution {
public:
    int threeSumClosest(vector<int>& nums, int target) {
        sort(nums.begin(), nums.end());
        pair<int, int> res(INT_MAX, 0);
        for (int i = 0; i < nums.size(); i++)
        {
            for (int j = i + 1, k = nums.size() - 1; j < k; j++)
            {
                while (j < k - 1 && nums[i] + nums[j] + nums[k - 1] >= target) k--;
                int s1 = nums[i] + nums[j] + nums[k], s2 = nums[i] + nums[j] + nums[k - 1];
                res = min(res, make_pair(abs(s1 - target), s1));  // 不一定会大于等于0,因此要用abs
                if (j < k - 1)  // 确保j和k-1不是一样的才能使用nums[k-1]
                    res = min(res, make_pair(target - s2, s2));  // 一定小于0
            }
        }
        return res.second;
    }
};

LeetCode 17. 电话号码的字母组合(中等)

【题目描述】

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

在这里插入图片描述

【示例1】

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

【示例2】

输入:digits = ""
输出:[]

【示例3】

输入:digits = "2"
输出:["a","b","c"]

【提示】

0 ≤ d i g i t s . l e n g t h ≤ 4 0\le digits.length\le 4 0digits.length4
digits[i] 是范围 ['2', '9'] 的一个数字。

【分析】


直接 DFS 爆搜即可。


【Python代码】

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        d2str = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
        res = []
    
        def dfs(digits: str, u: int, now: str):
            if u == len(digits):
                res.append(now)
                return
            for c in d2str[int(digits[u])]:
                dfs(digits, u + 1, now + c)

        dfs(digits, 0, '')
        return [] if not digits else res

LeetCode 18. 四数之和(中等)

【题目描述】

给你一个由 n 个整数组成的数组 nums,和一个目标值 target。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]](若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • abcd 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按任意顺序返回答案 。

【示例1】

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

【示例2】

输入:nums = [2,2,2,2,2], target = 8
输出:[[2,2,2,2]]

【提示】

1 ≤ n u m s . l e n g t h ≤ 200 1\le nums.length\le 200 1nums.length200
− 1 0 9 ≤ n u m s [ i ] ≤ 1 0 9 -10^9\le nums[i]\le 10^9 109nums[i]109
− 1 0 9 ≤ t a r g e t ≤ 1 0 9 -10^9\le target\le 10^9 109target109

【分析】


和第15题一样,暴力枚举四个数时间复杂度为 O ( n 4 ) O(n^4) O(n4),使用双指针算法可以优化成 O ( n 3 ) O(n^3) O(n3)。需要注意本题四个数相加可能会溢出。


【代码】

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        for (int i = 0; i < nums.size(); i++)
            if (i && nums[i] == nums[i - 1]) continue;
            else for (int j = i + 1; j < nums.size(); j++)
                if (j > i + 1 && nums[j] == nums[j - 1]) continue;
                else for (int k = j + 1, u = nums.size() - 1; k < u; k++)
                {
                    if (k > j + 1 && nums[k] == nums[k - 1]) continue;
                    while (k < u - 1 && (long long)nums[i] + nums[j] + nums[k] + nums[u - 1] >= target) u--;
                    if ((long long)nums[i] + nums[j] + nums[k] + nums[u] == target)
                        res.push_back({ nums[i], nums[j], nums[k], nums[u] });
                }
        return res;
    }
};

http://www.niftyadmin.cn/n/4980628.html

相关文章

sql:SQL优化知识点记录(五)

&#xff08;1&#xff09;explain之例子 &#xff08;2&#xff09;索引单表优化案例 上面的功能已经实现&#xff0c;但是分析功能&#xff0c; 使用explain分析这条sql&#xff1a; 发现type为All Extra&#xff1a;有Using filesort &#xff08;文件内排序&#xff09; 这…

C# 使用SnsSharp实现文件拖拽功能

CSDN下载地址&#xff1a;https://download.csdn.net/download/sns1991sns/88041637 gitee下载地址&#xff1a;https://gitee.com/linsns/snssharp 技术优势&#xff1a; 不仅使用简单&#xff0c;还可解决由于系统管理权限导致的文件拖拽无响应问题。 使用举例&#xff1a…

Java接收json参数

JSON 并不是唯一能够实现在互联网中传输数据的方式&#xff0c;除此之外还有一种 XML 格式。JSON 和 XML 能够执行许多相同的任务&#xff0c;那么我们为什么要使用 JSON&#xff0c;而不是 XML 呢&#xff1f; 之所以使用 JSON&#xff0c;最主要的原因是 JavaScript。众所周知…

液冷技术之液冷连接器快速接头

文章目录 系列文章目录前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 热能在液冷技术的研发不断加大&#xff0c;特别是在水冷产品生产工艺上不断革新&#xff0c;在铜管自动折弯、挤型模、压管、粘连焊接等技术工艺获得了多个技术专利&#xff0…

Docker中容器的随机命名方式

使用 docker 创建容器时&#xff0c;如果没有用 --name 指定&#xff0c;docker 会为用户选择一个名称&#xff0c; 格式是两个带有下划线的单词&#xff0c;如xxx_yyyy 其相关的实现在此处 pkg/namesgenerator/names-generator.go[1] 源码中有两个数组&#xff0c;第一个是一个…

Redis 7 教程 数据持久化

总体 RDB 介绍 RDB 持久化以指定的时间间隔执行数据集的时间点快照 。 把某一时刻的数据和状态以文件的形式写到磁盘上,即使出现故障宕机,快照文件也不会丢失,数据的可靠性得到保证。快照文件就是RDB(Redis DataBase)文件(dump.rdb) 作用 在指定的时间间隔内将内存中的数…

Unity——音乐、音效

在游戏运行的过程中&#xff0c;音效的播放时机与游戏当前内容密切相关&#xff0c;而且随着场景的变化、剧情的推进&#xff0c;背景音乐也需要适时切换&#xff0c;所以恰当地控制音乐和音效的播放非常重要。音乐和音效的播放、停止、切换和音量变化等&#xff0c;都需要由脚…

ROS通信机制之服务(Service)的应用

1、服务的概述 在上节我们讲过一个重要通信机制话题&#xff1a;ROS通信机制之话题(Topics)的发布与订阅以及自定义消息的实现&#xff0c;这里介绍另外一种节点之间传递数据的方法&#xff1a;服务(Service)服务的本质是同步的跨进程函数调用&#xff0c;也就是说节点可以调用…