zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    第八周读书笔记 ——编程之美
    结对编程收获——旧的不去&新的不来
    第七周读书笔记——深入理解计算机系统
    第六周读书笔记——《编程珠玑(第二版)》
    专业性体育平台——虎扑的发展与创新的思考(第五次课后作业)
    第五次读书笔记—— Robrt C. Martin的《代码整洁之道》
    个人博客-ASE课程最后一周总结
    期中作业,阅读材料感想
    Poemscape beta版本第二阶段目标描述
    Poemscape|Beta阶段第二天
  • 原文地址:https://www.cnblogs.com/ZhongliangXiang/p/7485994.html
Copyright © 2011-2022 走看看