给定一个含不同整数的集合,返回其所有的子集,打败了92%

该算法有很多种解法,无外乎dfs bfs 递归与不递归,其实都差不多,我测了下运行速度也差不多,感觉lintcode 的提交有bug 每次提交运行速度不一样,我这套最开始运行250ms 后面又提交了次 跑了232ms
我主要加上了 快速排序 和二分查找 来降低排序和循环的次数 比参考答案快了几十ms

描述
中文
English
给定一个含不同整数的集合,返回其所有的子集。

子集中的元素排列必须是非降序的,解集必须不包含重复的子集。

您在真实的面试中是否遇到过这个题?
样例
样例 1:

输入:[0]
输出:
[
[],
[0]
]
样例 2:

输入:[1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

public class StackAndMin {
     
    public static void main(String[] args) {
     
//        System.out.println(strStr("source","se"));
        int[] nums={
     4,1,2,3};
        List<List<Integer>> subsets = subsets(nums);
        for (List<Integer> list : subsets) {
     
            for (Integer integer : list) {
     
                System.out.print(integer+" ");
            }
            System.out.println("---");
        }
//        quickSelect(0, nums.length - 1, nums);
//        System.out.println(nums[0]);
    }

    
    /**
     * @param nums: The integer array.
     * @param target: Target to find.
     * @return: The first position of target. Position starts from 0.
     */
    public static int binarySearch(int[] nums, int target) {
     
        // write your code here
        if (nums==null || nums.length==0){
     
            return -1;
        }
        int start=0;
        int end=nums.length-1;
        while (start<=end){
     
            int index=(start+end)/2;
            if (target<nums[index]){
     
                //左边
                end=index-1;
            }else if (target==nums[index]){
     
                //找到前一个小于此值得坐标
                int flag=index;
                if (flag==0 || flag==(nums.length-1)){
     
                    return flag;
                }
                while (target==nums[flag]){
     
                    flag--;
                }
                return flag+1;
            }else {
     
                //右边
                start=index+1;
            }
        }
        return -1;
    }

   
   

    /**
     * @param S: A set of numbers.
     * @return: A list of lists. All valid subsets.
     */
    public static List<List<Integer>> subsets(int[] nums) {
     
        List<List<Integer>> lists=new ArrayList<>();
        List<Integer> list=new ArrayList<>();
        if (nums==null || nums.length==0){
     
            lists.add(list);
            return lists;
        }
        Queue<List<Integer>> queue=new LinkedList<>();
        /**
         * TODO 对nums排序,这里运用我自己写的快速排序来进行解决
         *
         */
        quickSelect(0, nums.length - 1, nums);
//        Arrays.sort(nums);
//        queue.offer(); 添加
//        queue.poll(); 取出

        queue.offer(list);
        int count=0;
        while (queue.size()>0){
     
            List<Integer> poll = queue.poll();
            lists.add(poll);

            //用二分查找法查找下标
            int search=0;
            if (poll.size()==0){
     
               search=-1;
            }else {
     
                search = binarySearch(nums, poll.get(poll.size() - 1));
            }
            for (int i=search+1;i<nums.length;i++){
     
                List<Integer> aa=new ArrayList<>();
                aa.addAll(poll);
                aa.add(nums[i]);
                queue.offer(aa);
                count++;
            }
        }
        System.out.println("总共执行了"+count);
        return lists;
    }

    /**
     * 快速排序
     * @param left
     * @param right
     * @param nums
     * @param n
     */
    public static void quickSelect(int start, int end, int[] nums) {
     
        int pivot = nums[(start + end) / 2];
        int left = start;
        int right = end;
        while (left <= right) {
     
            while (nums[left] < pivot && left <= right) {
     
                left++;
            }
            while (nums[right] > pivot && left <= right) {
     
                right--;
            }
            if (left <= right) {
     
                //交换
                int swap = 0;
                swap = nums[right];
                nums[right] = nums[left];
                nums[left] = swap;
                left++;
                right--;
            }
        }
        if (right>start) {
     
            quickSelect(start, right, nums);
        }

        if (left<end) {
     
            quickSelect(left, end, nums);
        }


    }



}

你可能感兴趣的:(算法,java,算法)