• [LeetCode] Combinations


    题目: Combinations

    1-n个数字中找k个数字的所有不同组合。

    思路:从1-k开始,每次从k开始,让最后面的元素加1,超过了,就让前面一个元素加1,后面一个元素变为前面一个元素的值加1.

    循环知道所有元素都没有超过,则是一种不同的情况。

    例如:n = 6,k = 4;

    1234->1235->1236->1245->1246->1256->1345->1346->1356->1456

    ->2345->...->3456

    package com.example.medium;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    
    public class Combinations {
        public List<List<Integer>> combine(int n, int k) {
            List<List<Integer>> list = new LinkedList<>();
            int indexs[] = new int[k];
            int j = 0;
            for(int i = 0;i < k;i++){
                indexs[i] = i;
            }
            while(indexs[0] <= n - k){
                List<Integer> item = new ArrayList<Integer>(k);
                for(int i = 0;i <k;i++){//添加当前的k个元素
                    item.add(i, indexs[i] + 1);
                }
                    list.add(item);
                    j = k - 1;
                    indexs[j]++;//最后一个元素加一
                    while(indexs[j] >= n - k + j + 1){//超过了n则倒数第二个元素加一,然后判断是否超过n,如此循环
                        j--;
                        if(j < 0)break;
                        indexs[j]++;
                    }
                    for(;j >= 0 && j < k - 1;j++)
                        indexs[j + 1] = indexs[j] + 1;
            }
            return list;
        }
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            List<List<Integer>> list = new Combinations().combine(17, 5);
            Iterator<List<Integer>> iterator = list.iterator();
            while(iterator.hasNext()){
                List<Integer> item = iterator.next();
                for(int i = 0;i < item.size();i++)
                    System.out.print(item.get(i) + " ");
                System.out.println();
            }
    
        }
    
    }

     题目:Subsets

    找到给定数组的所有子集;数组中每个元素都不同

    思路:

    和上面一样,不过这次没有固定的k值。

    让k从0开始一直加到n(数组长度),然后按照上面的方法找到所有子集。

    package com.example.medium;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    
    public class Subsets {
        public List<List<Integer>> subsets(int[] nums) {
          List<List<Integer>> list = new LinkedList<>();
          int index[] = new int[nums.length];//存储元素下标
          int i = 0,k = 0;
          while (i <= nums.length) {
                    List<Integer> item = new ArrayList<>(i);
                    for (int j = 0; j < i; j++) {//添加子集
                        item.add(j, nums[index[j]]);
                    }
                    list.add(item);
                    k = i - 1;//k减一
                    if(k < 0){//元素个数为i的子集找完了
                        i++;
                        continue;
                    }
                    index[k]++;//最后一个元素的下标加一
                    while(index[k] > nums.length - i + k){
                        k--;//
                        if(k < 0)break;
                        index[k]++;
                    }
                    if(k < 0){//元素个数为i的子集找完了
                        i++;
                        if(i > nums.length)break;
                        for (int j = 0; j < i; j++) {//当i增加时,重新初始化
                            index[j] = j;
                        }
                    }else{
                        for(;k < i - 1;k++)
                            index[k + 1] = index[k] + 1;
                    }
                }
          return list;
        }
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            List<List<Integer>> list = new Subsets().subsets(new int[]{1,2,3,4,5,6});
            Iterator<List<Integer>> iterator = list.iterator();
            while(iterator.hasNext()){
                List<Integer> item = iterator.next();
                for(int i = 0;i < item.size();i++)
                    System.out.print(item.get(i) + " ");
                System.out.println();
            }
    
        }
    
    }

    题目:SubsetsII

    找到给定数组的所有子集;数组中有相同元素。

    思路:

    和上面的相同,但是在查找前先排序,然后每次跳过元素之相同的元素。

    package com.example.medium;
    
    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],
     *   []
     * ]
     * @author qfp
     *
     */
    public class SubSets2 {
        public List<List<Integer>> subsetsWithDup(int[] nums) {
            List<List<Integer>> list = new LinkedList<List<Integer>>();
            Arrays.sort(nums);
            int[] index = new int[nums.length];//记录当前情况的下标
            int i = 0,k = 0;//i表示子集中元素的个数
            while(i <= nums.length){
                List<Integer> item = new ArrayList<Integer>(i);
                for (int j = 0; j < i; j++) {//将当前情况添加进去
                    item.add(j, nums[index[j]]);
                }
                list.add(item);
                k = i - 1;//更新当前子集个数为i时,新的可能的子集
                if(k < 0){//当i = 0时,只有一个空集
                    i++;
                    continue;
                }
                //先更新id最大的元素,去重
                while(index[k] < nums.length - 1 && nums[index[k]] == nums[index[k] + 1])index[k]++;
                index[k]++;
                while(index[k] > nums.length - i + k){
                    k--;//
                    if(k < 0)break;//k小于0时,表示个数为i的子集全部找到了
                    while(index[k] < nums.length - 1 && nums[index[k]] == nums[index[k] + 1])index[k]++;
                    index[k]++;
                }
                if(k < 0){
                    i++;
                    if(i > nums.length)break;
                    for (int j = 0; j < i; j++) {//当i增加时,重新初始化
                        index[j] = j;
                    }
                }else{
                    for(;k < i - 1;k++)
                        index[k + 1] = index[k] + 1;
                }
            }
            return list;
        }
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            List<List<Integer>> list = new SubSets2().subsetsWithDup(new int[]{1,2,2,1,1});
            Iterator<List<Integer>> iterator = list.iterator();
            while(iterator.hasNext()){
                List<Integer> item = iterator.next();
                for(int i = 0;i < item.size();i++)
                    System.out.print(item.get(i) + " ");
                System.out.println();
            }
    
        }
    
    }
  • 相关阅读:
    进程与线程
    the art of seo(chapter seven)
    the art of seo(chapter six)
    the art of seo(chapter five)
    the art of seo(chapter four)
    the art of seo(chapter three)
    the art of seo(chapter two)
    the art of seo(chapter one)
    Sentinel Cluster流程分析
    Sentinel Core流程分析
  • 原文地址:https://www.cnblogs.com/yeqluofwupheng/p/6685394.html
Copyright © 2020-2023  润新知