• 90. Subsets II(中等,编写代码有难度)


    Given a collection of integers that might contain duplicates, nums, return all possible subsets.

    Note: The solution set must not contain duplicate subsets.

    For example,
    If nums = [1,2,2], a solution is:

    [
     [2],
     [1],
     [1,2,2],
     [2,2],
     [1,2],
     []
    ]
    

    有重复值的序列的所有子集.
    核心想法是:
    把 [2,2] 看成1个特殊的元素,它不想其他元素只有两种状态(存在,不存在).
    This element([2, 2]) has more than two choices: you can either NOT put it into the subset, or put ONE 2 into the subset, or put TWO 2s into the subset.
    上面是老外的解释,很精彩且到位.

    这题,对我来说,即使知道想法,编这个东西难度也挺大.
    仔细考察人家的代码后,发现下面的事实:

    下面程序生成序列的顺序如下:
    
    [[]]->[[],[1]]->[[],[1],[2],[2,2],[1,2],[1,2,2]]
                             |<- []->| |<-  [1]  ->|
    
    |<- []->| 这个地方代表 [2],[2,2] 是由 [] 生成的;
    |<-[1]->| 这个地方代表 [1,2],[1,2,2] 是由 [1] 生成的.
    

    了解了上述生成顺序,下面的代码就好理解了.

    人家想法,复写人家代码(那想法好难实现).
    有三个亮点:

    1. i += count; // smart~!
    2. 以 i 为 base,对 count 计数: while (count + i < A.size() && A[count + i] == A[i]) count++;
    3. preN 保存了 res 未改变前的长度;
    4. 用一个 vector 保存 res[k]: vector<int> inst = res[k]; // [].
      • 这个太重要了,因为可以实现 [1] -> [1,2](store this in res) -> [1,2,2](store this value in res again base on [1, 2])

    (O(n^2)) time, (O(1)) extra space.

    // sample: A = [1, 2, 2]
    // 即使知道想法,编这个东西难度也挺大
    // 把 2,2 看成一个特殊的元素.
    // 可以出现1个2, 也可以出现两个2
    // 下面程序生成序列的顺序如下:
    // [[]]->[[],[1]]->[[],[1],[2],[2,2],[1,2],[1,2,2]]
    //                         |<- []->| |<-  [1]  ->|
    vector<vector<int>> subsetsWithDup(vector<int>& A) {
    	sort(A.begin(), A.end());
    	vector<vector<int> > res = { {}}; //[[],]
    
    	for (int i = 0; i < A.size();) {
    
    		// 以 indx = i 为base
    		// 在A中向后查和A[i]相同的元素个数 -> count
    		int count = 0;
    		while (count + i < A.size() && A[count + i] == A[i]) count++;
    
    		// res 未改之前的长度 -- 初始时,这个熊样--> res = [[]]
    		int preN = res.size();
    		for (int k = 0; k < preN; k++) {
    			vector<int> inst = res[k]; // []
    
    			for (int j = 0; j < count; j++) {
    				// e.g. 若 inst = []
    				// when j = 0, inst = [2]
    				//      j = 1, inst = [2, 2]
    				// inst 所代表的 array 都将送入 res
    				inst.push_back(A[i]);
    				res.push_back(inst);
    			}
    		}
    		i += count; // smart~!
    	}
    	return res;
    }
    
  • 相关阅读:
    (原创)攻击方式学习之(4) 拒绝服务(DOS/DDOS/DRDOS)
    gdb调试程序
    找找看XSS漏洞!!!
    C++实现发送HTTP请求
    Python天天美味(32) python数据结构与算法之堆排序
    (原创)攻击方式学习之(3) 缓冲区溢出(Buffer Overflow)
    Python天天美味(30) python数据结构与算法之快速排序
    CoderZh首款Python联机对战游戏 NancyTetris1.0倾情发布(一)
    ASCII表查看
    wxpython学习笔记
  • 原文地址:https://www.cnblogs.com/ZhongliangXiang/p/7485994.html
Copyright © 2020-2023  润新知