小明思考

          Just a software engineer
          posts - 124, comments - 36, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Subsets

          Posted on 2013-05-21 22:50 小明 閱讀(2122) 評論(0)  編輯  收藏 所屬分類: 數據結構和算法
          Problem

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

          Note:

          • Elements in a subset must be in non-descending order.
          • The solution set must not contain duplicate subsets.

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

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

          分析:
          因為要求結果集是升序排列,所以首先我們要對數組進行排序。

          子集的長度可以從0到整個數組的長度。長度為n+1的子集可以由長度為n的子集再加上在之后的一個元素組成。

          這里我使用了三個技巧
          1。使用了一個index數組來記錄每個子集的最大索引,這樣添加新元素就很簡單。
          2。使用了兩個變量start和end來記錄上一個長度的子集在結果中的起始和終止位置。
          3。去重處理使用了一個last變量記錄前一次的值,它的初始值設為S[0]-1,這樣就保證了和數組的任何一個元素不同。

          代碼如下:
          public class Solution {
              public ArrayList<ArrayList<Integer>> subsetsWithDup(int[] S) {
                  Arrays.sort(S);
                  
                  ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
                  ArrayList<Integer> indexs = new ArrayList<Integer>();
                  result.add(new ArrayList<Integer>());
                  indexs.add(-1);
                  
                  int slen = S.length;
                  int start=0,end=0;
                  for(int len=1;len<=slen;++len){
                      int e = end;
                      for(int i=start;i<=end;++i){
                          ArrayList<Integer> ss = result.get(i);
                          int index = indexs.get(i).intValue();
                          int last = S[0]-1;
                          for(int j = index+1;j<slen;++j){
                              int v = S[j];
                              if(v!=last){
                                  ArrayList<Integer> newss = new ArrayList<Integer>(ss);
                                  newss.add(v);
                                  result.add(newss);
                                  indexs.add(j);
                                  ++e;
                                  last = v;
                              }
                          }
                      }
                      
                      start = end+1;
                      end = e;
                  }
                  return result;
              }
          }
          主站蜘蛛池模板: 白银市| 文山县| 安西县| 镇远县| 调兵山市| 莱芜市| 彩票| 泰州市| 衡阳县| 镇雄县| 朝阳市| 六安市| 辽宁省| 乐安县| 大余县| 广德县| 平顶山市| 广州市| 涟水县| 灵寿县| 资中县| 上蔡县| 邢台市| 嵩明县| 无为县| 乌拉特后旗| 黄梅县| 霍林郭勒市| 辽中县| 龙州县| 阳泉市| 新余市| 会理县| 阳原县| 柘荣县| 宁津县| 社旗县| 潼南县| 曲松县| 镇巴县| 芒康县|