leetcode——第491题——递增子序列

题目:
给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是 2 。

/*
 这道题对比前面的题,有两处需要注意的:
    1、这题是不能对给定数组排序的,因为是要求找给定数组的顺序找其子序列,既然是子序列那顺序就不能变
    2、既然不能排序,那么相同的元素就不一定是挨着的,所以,就不能是相邻元素做比较,就要用哈希映射每个元素是否取过

set 的一个没见过的用法
    uset.find(nums[i] != uset.end())

vector 的一个没见过的用法
    path.back()

    // 错误代码记录 这个是在回溯函数中的
        if(path.size() > 1)
        {
            // for(int i = 0; i < path.size()-1;i++)
            // {
            //     if(path[i] > path[i+1])
            //     {
            //         return;
            //     }
            // }
            // 1、这里的逻辑在for循环里取了
            // 2、这里不写 ruturn 
            result.push_back(path);
        }
        // // 其实这个等号,还是有点萌萌哒~~~~
        // 这里的终止条件完全可以不要的,因为在for循环中,当到达最后一位时自然会终止滴
        // if(startIndex == nums.size())
        // {
        //     return;
        // }
*/

// 法一::用 unordered_map 实现 哈希映射
class Solution {
private:
    vector<int> path;
    vector<vector<int>> result;
    void backtracking(vector<int>& nums, int startIndex)
    {
            if(path.size() > 1)
        {
                        result.push_back(path);
        }
        // 这里 mp 数组定义注意不是全局变量,而是仅仅针对这一层而言的变量,因为是同一层不能重复出现
        unordered_map<int, int> mp;     // key=元素值  value = 出现次数,如果出现次数大于1,则说明重复
        for(int i = startIndex; i < nums.size(); ++i)
        {
            // 判断是否是递增的逻辑放在了这里来处理
            // 树层去重的逻辑也在这里
            // 注意计数值的自增运算放的位置,放在 if 前,放在 if 后就错了
/***啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊阿啊啊啊*/
// 这里想明白   if语句中的(mp[nums[i]] > 1 )这个条件和   mp[nums[i]]++;  放在 if 前还是放 if 后的关系了
// 以下的两种写法都是对哒!!!棒棒哒~
            // 写法一:::
            // mp[nums[i]]++;
            // if((mp[nums[i]] > 1 ) || (!path.empty() && nums[i] < path.back()))
            // {
            //     continue;
            // }
            // path.push_back(nums[i]);
            // backtracking(nums, i + 1);
            // path.pop_back();

            // 写法二::::
            if((mp[nums[i]] == 1 ) || (!path.empty() && nums[i] < path.back()))
            {
                continue;
            }
            mp[nums[i]]++;
            path.push_back(nums[i]);
            backtracking(nums, i + 1);
            path.pop_back();
            
        }
    }

public:
    vector<vector<int>> findSubsequences(vector<int>& nums) 
    {
        path.clear();
        result.clear();
        backtracking(nums, 0);
        return result;
    }
};

// // 法二::用 unordered_set 实现哈希映射
// // path.back()
// // uset.find(nums[i] != uset.end())
// class Solution {
// private:
//     vector<int> path;
//     vector<vector<int>> result;
//     void backtracking(vector<int>& nums, int startIndex)
//     {
//         if(path.size() > 1)
//         {
//             result.push_back(path);
//         }
//         // 这里 mp 数组定义注意不是全局变量,而是仅仅针对这一层而言的变量,因为是同一层不能重复出现
//         unordered_set<int> uset;     // 使用uset记录出现过的元素
//         for(int i = startIndex; i < nums.size(); ++i)
//         {
//             // 判断是否是递增的逻辑放在了这里来处理
//             // 树层去重的逻辑也在这里
//             // 注意计数值的自增运算放的位置,放在 if 前,放在 if 后就错了
//             if((uset.find(nums[i]) != uset.end()) || (!path.empty() && nums[i] < path.back()))
//             {
//                 continue;
//             }
//             uset.insert(nums[i]);   // 记录这个元素在本层用过了,本层后面不能再用
//             path.push_back(nums[i]);
//             backtracking(nums, i + 1);
//             path.pop_back();
//         }
//     }

// public:
//     vector<vector<int>> findSubsequences(vector<int>& nums) 
//     {
//         path.clear();
//         result.clear();
//         backtracking(nums, 0);
//         return result;
//     }
// };

// // 法三::用 数组 实现 哈希映射
// // 因为本题说明了数值的范围是 [-100, 100],所以完全可以用数组来做哈希
// class Solution {
// private:
//     vector<int> path;
//     vector<vector<int>> result;
//     void backtracking(vector<int>& nums, int startIndex)
//     {
//         if(path.size() > 1)
//         {
//             result.push_back(path);
//         }
//         // 这里 mp 数组定义注意不是全局变量,而是仅仅针对这一层而言的变量,因为是同一层不能重复出现
//         int used[201] = {0};    // 定义一个大小为 201 的数组,并将其均初始化为 0 ,
//         for(int i = startIndex; i < nums.size(); ++i)
//         {
//             // 判断是否是递增的逻辑放在了这里来处理
//             // 树层去重的逻辑也在这里
//             // 注意计数值的自增运算放的位置,放在 if 前,放在 if 后就错了
//             if((used[nums[i] + 100 ]== 1) || (!path.empty() && nums[i] < path.back()))
//             {
//                 continue;
//             }
//             // 因为元素的范围是 [-100, 100],所以将其映射到 [0 , 200],如果出现过,则将对应位置上赋值为1
//             used[nums[i] + 100] = 1;
//             path.push_back(nums[i]);
//             backtracking(nums, i + 1);
//             path.pop_back();
//         }
//     }

// public:
//     vector<vector<int>> findSubsequences(vector<int>& nums) 
//     {
//         path.clear();
//         result.clear();
//         backtracking(nums, 0);
//         return result;
//     }
// };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值