(81)491. Increasing subsequence (leetcode).

题目链接:
https://leetcode-cn.com/problems/increasing-subsequences/
难度:中等
491. 递增子序列
	给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。
示例:
	输入: [4, 6, 7, 7]
	输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]
说明:
	给定数组的长度不会超过15。
	数组中的整数范围是 [-100,100]。
	给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。

I'm going to die with a headache, toothache, and throat discomfort. . . . I don’t know how to do it, and I don’t want to do it. Just look at the answer. The
first method is very
easy to understand. There are a total of 2 to the nth power. All enumerate once to determine whether it is an increasing subsequence. Whether it is repeated (I don’t know much about this place) The
possible situation of using binary records

	几个例子吧: 序列 { 1  2  3 }
	共有8中情况 : 
			   { 1   2   3  }    对应数字(十进制)
				 0   0   0               0
				 0   0   1               1
				 0   1   0               2
				 0   1   1               3
				 1   0   0               4
				 1   0   1               5
				 1   1   0               6
				 1   1   1               7
	0 代表没有该数字  1代表选中该数字 当然其中有不符合条件的 

For the formula for finding the hash value:

p can go to any value greater than or equal to max{ai​}+1

class Solution {
    
    
public:
    vector<int> temp;
    vector<vector<int>> ans;
    unordered_set<int> s;
    int n;
    
    // 找出 对应的数字
    void findSubsequences(int mask, vector<int>& nums) {
    
    
        temp.clear();
        for (int i = 0; i < n; ++i) {
    
    
            if (mask & 1) {
    
    
                temp.push_back(nums[i]);
            }
            mask >>= 1;
        }
    }
    // 判断 子序列(temp) 是不是递增子序列
    bool check() {
    
    
        for (int i = 1; i < temp.size(); ++i) {
    
    
            if (temp[i] < temp[i - 1]) {
    
    
                return false;
            }
        }
        return temp.size() >= 2;
    }
    // 得到hash值
    int getHash(int base, int mod) {
    
    
        int hashValue = 0;
        for (const auto &x: temp) {
    
    
            hashValue = 1LL * hashValue * base % mod + (x + 101);
            hashValue %= mod;
        }
        return hashValue;
    }

    vector<vector<int>> findSubsequences(vector<int>& nums) {
    
    
        n = nums.size();
        // 共有 2的n次方 种情况 即 1<<n
        // 数字 i 所对应的子序列
        for (int i = 0; i < (1 << n); ++i) {
    
    
            // 将找出的子序列放到 temp 中
            findSubsequences(i, nums);
            // 求出 hash 值
            int hashValue = getHash(263, int(1E9) + 7);
            // 递增 不存在
            if (check() && s.find(hashValue) == s.end()) {
    
    
                ans.push_back(temp);
                s.insert(hashValue);
            }
        }
        return ans;
    }

};

The other is recursion or recursive convenience,
or enumerating each number. There are two cases to choose or not to choose. When one of the cases enumerates to the end of the sequence, it ends (a parameter is required to record the current position).
When selecting, only when the current value is greater than Only the last value can be selected. This satisfies the increment of the sequence and also solves the non-repetition of the sequence.
For... a… b… (cur points to ba at this time is the last selected element) For the sequence ab, there are four cases for a selection and b selection a select b not select a not select b select a not select b not select
If the value of ab is the same, it can be seen that a selects b does not select a does not select b is equivalent, as long as one is excluded, then only the previous element is not equal When the current element is not selected

class Solution {
    
    
public:
    vector<int> temp;
    vector<vector<int>> ans;

    void dfs(int cur,int last,vector<int>& nums){
    
    
        int n = nums.size();
        // 递归条件 枚举至端点跳出
        if(n==cur){
    
    
            if(temp.size()>=2){
    
    
                ans.push_back(temp); 
            }
            return;
        }
        // 若当前值大于前一个值
        //   相当于 
        //     temp.push_back(nums[cur]);
        //     dfs(cur+1,nums[cur],nums);
        //     temp.pop_back();
        //     dfs(cur+1,last,nums);
        // 若当前值等于前一个值
        //     temp.push_back(nums[cur]);
        //     dfs(cur+1,nums[cur],nums);
        //     temp.pop_back();
        //     {不选择当前元素} 此种情况排除
        if(nums[cur]>=last){
    
    
            temp.push_back(nums[cur]);
            dfs(cur+1,nums[cur],nums);
            temp.pop_back();
        }
        if(nums[cur]!=last){
    
    
            dfs(cur+1,last,nums);
        }
    }

    vector<vector<int>> findSubsequences(vector<int>& nums) {
    
    
        dfs(0, INT_MIN, nums);
        return ans;
    }

};

First of all, it’s a bit uncomfortable to sleep in recent days,,,

Guess you like

Origin blog.csdn.net/li_qw_er/article/details/108216663