代码随想录算法训练营第二十四天|LeetCode 77.组合

77.组合

题目描述:
给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。

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

示例一:

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]

示例二:

输入:n = 1, k = 1
输出:[[1]]

提示:

1 <= n <= 20
1 <= k <= n

解题思路:

  1. 关键词提取:两个整数、数值范围[1,n]、k个数组合、任意顺序
  2. 回溯解法:
    1. 层数k,在达到k层时,将结果保存
    2. 选值范围[1,n],由for循环做遍历寻值
    3. 每个值只能用一次,需要用index去记录起始位置,每层从起始位置开始寻值

代码如下:

class Solution {
private:
    // 定义一个储存返回结果的二维数组
    vector<vector<int>> result;
    // 定义一个储存单次结果的一维数组
    vector<int> path;
    // 递归函数,需要传递的参数有数值范围n,层数k,起始位置startIndex
    void backtracking(int n, int k, int startIndex) {
        // 终止条件,单次结果的数组长度达到层数k
        if(path.size() == k) {
            // 将单次结果放入到二维数组中
            result.push_back(path);
            return;
        }
        // 做单层取数遍历,从起始位置开始,每层的起始位置不一样
        for(int i = startIndex; i <= n; i++) {
            // 将当前值放入到单次结果数组中
            path.push_back(i);
            // 递归,从下一个值开始遍历
            backtracking(n, k, i + 1);
            // 将当前值从单次结果数组中删除,回溯
            path.pop_back();
        }
    }
public:
    vector<vector<int>> combine(int n, int k) {
        result.clear();
        path.clear();
        // 题目取值范围从1-n
        backtracking(n, k, 1);
        return result;
    }
};

总结:

  1. 二刷,采用回溯算法的模板去做,逻辑很清晰。

    1. 解题:组合类,元素不能重复,任意顺序。满足回溯法的前提条件。
    2. 模板:
      1、确认递归函数
      2、确认递归终止条件
      3、确认结果集的存数逻辑
      4、确认单层遍历的起始位置
      5、确认单次结果取数逻辑
      6、确认递归函数的起始状态
      7、确认单次递归的回溯逻辑
  2. 代码随想录讲解的很详细,有兴趣的小伙伴可以去研究一下。

    1. 讲解视频:https://www.bilibili.com/video/BV1ti4y1L7cv/
    2. 值得深究的地方:剪枝和去重,我理解还不够,建议大家伙儿还是直接去看carl哥的讲解视频比较合适。
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
第二十二算法训练营主要涵盖了Leetcode题目中的三道题目,分别是Leetcode 28 "Find the Index of the First Occurrence in a String",Leetcode 977 "有序数组的平方",和Leetcode 209 "长度最小的子数组"。 首先是Leetcode 28题,题目要求在给定的字符串中找到第一个出现的字符的索引。思路是使用双指针来遍历字符串,一个指向字符串的开头,另一个指向字符串的结尾。通过比较两个指针所指向的字符是否相等来判断是否找到了第一个出现的字符。具体实现的代码如下: ```python def findIndex(self, s: str) -> int: left = 0 right = len(s) - 1 while left <= right: if s[left == s[right]: return left left += 1 right -= 1 return -1 ``` 接下来是Leetcode 977题,题目要求对给定的有序数组中的元素进行平方,并按照非递减的顺序返回结果。这里由于数组已经是有序的,所以可以使用双指针的方法来解决问题。一个指针指向数组的开头,另一个指针指向数组的末尾。通过比较两个指针所指向的元素的绝对值的大小来确定哪个元素的平方应该放在结果数组的末尾。具体实现的代码如下: ```python def sortedSquares(self, nums: List[int]) -> List[int]: left = 0 right = len(nums) - 1 ans = [] while left <= right: if abs(nums[left]) >= abs(nums[right]): ans.append(nums[left ** 2) left += 1 else: ans.append(nums[right ** 2) right -= 1 return ans[::-1] ``` 最后是Leetcode 209题,题目要求在给定的数组中找到长度最小的子数组,使得子数组的和大于等于给定的目标值。这里可以使用滑动窗口的方法来解决问题。使用两个指针来表示滑动窗口的左边界和右边界,通过移动指针来调整滑动窗口的大小,使得滑动窗口中的元素的和满足题目要求。具体实现的代码如下: ```python def minSubArrayLen(self, target: int, nums: List[int]) -> int: left = 0 right = 0 ans = float('inf') total = 0 while right < len(nums): total += nums[right] while total >= target: ans = min(ans, right - left + 1) total -= nums[left] left += 1 right += 1 return ans if ans != float('inf') else 0 ``` 以上就是第二十二算法训练营的内容。通过这些题目的练习,可以提升对双指针和滑动窗口等算法的理解和应用能力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值