LeetCode090 Subsets II

详细见:leetcode.com/problems/subsets-ii


Java Solution: github

package leetcode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/*
 * 	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],
	  []
	]
 */

public class P090_SubsetsII {
	public static void main(String[] args) {
		int[] nums = null;
		nums = new int[] {1, 1, 2, 2, 3, 3};
		List<List<Integer>> ans = new Solution().subsetsWithDup(nums);
		Iterator<List<Integer>> it = ans.iterator();
		while (it.hasNext()) {
			tools.Utils.B_打印List_Integer_OneLine(it.next());
		}
	}
	/*
	 * 	AC
	 * 	无论何时,都需要耐心分析边界问题。
	 * 	3 ms
	 */
	static class Solution {
		List<List<Integer>> ans = new LinkedList<>();
		int[] first_same, last_same, record, nums;
	    public List<List<Integer>> subsetsWithDup(int[] nums) {
	    	ans.add(new LinkedList<Integer>());
	    	if (nums == null || nums.length == 0) {
	    		return ans;
	    	}
	    	Arrays.sort(nums);
	    	this.nums = nums;
	    	first_same = new int[nums.length];
	    	last_same = new int[nums.length];
	    	record = new int[nums.length];
	    	for (int i = 0; i != nums.length; i ++) {
	    		if (0 == i || nums[i - 1] != nums[i]) {
	    			first_same[i] = i;
	    		} else {
	    			first_same[i] = first_same[i - 1];
	    		}
	    	}
	    	for (int i = nums.length - 1; i > - 1; i --) {
	    		if (i == nums.length - 1 || nums[i] != nums[i + 1]) {
	    			last_same[i] = i;
	    		} else {
	    			last_same[i] = last_same[i + 1];
	    		}
	    	}
//	    	tools.Utils.printArray(first_same, 10);
//	    	tools.Utils.printArray(last_same, 10);
	    	for (int len = 1; len <= nums.length; len ++) {
	    		search(len, 0, 0);
	    	}
	        return ans;
	    }
		private void search(int len, int len_now, int sti) {
			if (len_now == len) {
				List<Integer> temp = new ArrayList<Integer>(len);
				for (int i = 0; i != len; i ++) {
					temp.add(record[i]);
				}
				ans.add(temp);
				return;
			}
			for (int i = sti; i < nums.length; i ++) {
				if (first_same[i] == last_same[i]) {
					record[len_now] = nums[i];
					search(len, len_now + 1, i + 1);
				} else {
					int count_same = last_same[i] - first_same[i];
					for (int same_now = 0; same_now <= count_same; same_now ++) {
						if (len_now + same_now >= len) {
							break;
						}
//						if (same_now != 0) {
						record[len_now + same_now] = nums[i];
//						}
						search(len, len_now + same_now + 1, last_same[i] + 1);
					}
					i += count_same;
				}
			}
		}
	}
}


C Solution: github

/*
    url: leetcode.com/problems/subsets-ii
    AC 3ms 70.59%
*/

#include <stdio.h>
#include <stdlib.h>

typedef int* T;
typedef struct al sal;
typedef struct al * pal;

struct al {
    int capacity;
    int size;
    T* arr;
};

pal al_init(int capacity) {
    pal l = (pal) malloc(sizeof(sal));
    if (capacity < 1) return NULL;
    l->arr = (T*) malloc(sizeof(T) * capacity);
    l->capacity = capacity;
    l->size = 0;
    return l;
}

void al_expand_capacity(pal l) {
    T* new_arr = (T*) malloc(sizeof(T) * (l->capacity * 2 + 1));
    int i = 0;
    for (i = 0; i < l->capacity; i ++)
        new_arr[i] = l->arr[i];
    free(l->arr);
    l->arr = new_arr;
    l->capacity = l->capacity * 2 + 1;
}

void al_add_last(pal l, T v) {
    if (l->capacity == l->size) al_expand_capacity(l);
    l->arr[l->size] = v;
    l->size ++;
}

T* al_convert_to_array_free_l(pal l) {
    T* arr = l->arr;
    free(l);
    return arr;
}

void al_free(pal l) {
    int i = 0;
    for (i = 0; i < l->size; i ++)
        free(l->arr[i]);
    free(l->arr);
    free(l);
}

int partition(int* n, int i, int j) {
    int s = n[i];
    while (i < j) {
        while (i < j && n[j] >= s) j --;
        n[i] = n[j];
        while (i < j && n[i] <= s) i ++;
        n[j] = n[i];
    }
    n[i] = s;
    return i;
}

void quick_sort(int* n, int i, int j) {
    int p = 0;
    if (i+1 < j) {
        p = partition(n, i, j-1);
        quick_sort(n, i, p);
        quick_sort(n, p+1, j);
    }
}

int* arr_copy(int* s, int sn) {
    int* t = (int*) malloc(sizeof(int) * sn);
    int i = 0;
    for (i = 0; i < sn; i ++) {
        t[i] = s[i];
    }
    return t;
}

int* arr_int(int val) {
    int* t = (int*) malloc(sizeof(int));
    t[0] = val;
    return t;
}

void search(pal l, pal ln, int* n, int ni, int nn, int* s, int si, int sn, int sign) {
    int i = 0;
    if (si == sn && ni == nn) {
        al_add_last(l, arr_copy(s, sn));
        al_add_last(ln, arr_int(sn));
        return;
    }
    if (ni >= nn || si > sn) return;
    if (! (sign && ni != 0 && n[ni-1] == n[ni])) {
        search(l, ln, n, ni+1, nn, s, si, sn, 0);
    }
    if (si < sn) s[si] = n[ni];
    search(l, ln, n, ni+1, nn, s, si+1, sn, 1);
}

int** subsetsWithDup(int* n, int nn, int** cn, int* rn) {
    pal l = NULL, ln = NULL;
    int ni = 0, *s = NULL, si = 0;
    if (n == NULL || nn < 1) return NULL;
    quick_sort(n, 0, nn);
    l = al_init(16);
    ln = al_init(16);
    s = (int*) malloc(sizeof(int) * nn);
    for (ni = 0; ni <= nn; ni ++) {
        search(l, ln, n, 0, nn, s, 0, ni, 0);
    }
    *rn = l->size;
    *cn = (int*) malloc(sizeof(int) * *rn);
    for (si = 0; si < *rn; si ++)
        (*cn)[si] = ln->arr[si][0];
   al_free(ln);
   return al_convert_to_array_free_l(l);
}

int main() {
    int n[] = {1,4,3,5,4,4,7,7,8,0};
    int nn = 2;
    int rn = 0;
    int* cn = NULL;
    int** a = subsetsWithDup(n, nn, &cn, &rn);
    int i = 0, j = 0;
    for (i = 0; i < rn; i ++) {
        for (j = 0; j < cn[i]; j ++) {
            printf("%d ", a[i][j]);
        }
        printf("\r\n");
        free(a[i]);   
    }
    free(a);
}


Python Solution: github

#coding=utf-8

'''
    url: leetcode.com/problems/subsets-ii
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年4月22日
    @details:    Solution: 65ms 71.66%
'''

class Solution(object):
    def search(self, n, ni, nn, r, ri, rn, iu, a):
        if ni == nn and ri == rn:
            a.append(list(r))
        if ni >= nn or ri > rn: return
        if not (ni != 0 and iu and n[ni-1]==n[ni]):
            self.search(n, ni+1, nn, r, ri, rn, False, a)
        if ri < rn: r[ri] = n[ni]
        self.search(n, ni+1, nn, r, ri+1, rn, True, a)
        
    def subsetsWithDup(self, n):
        """
        :type n: List[int]
        :rtype: List[List[int]]
        """
        nn = 0 if n == None else len(n)
        if nn == 0: return []
        n.sort(key=None, reverse=False)
        a = []
        for rn in range(nn+1):
            r = [0]*rn
            self.search(n, 0, nn, r, 0, rn, False, a)
        return a

if __name__ == "__main__":
    a = Solution().subsetsWithDup([1,2,2,2])
    print(a)
        


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值