该算法有很多种解法,无外乎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);
}
}
}