剑指Offer:第三题
在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,找出数组中所有重复的数字。
解法一:
先排序在寻找
采用快速排序,时间复杂度是O(nlog(n))
package algorithm.test3; import java.util.Arrays; import java.util.HashSet; public class Q1 { public static void main(String[] args) { int[] test = new int[]{2, 3, 1, 0, 2, 5, 3}; quickSort(0,test.length - 1,test); HashSet<Integer> integers = new HashSet<>(); System.out.println(Arrays.toString(test)); for (int i = 0; i < test.length; i++) { if (i == 0) { continue; } if (test[i-1] == test[i]) { integers.add( test[i]); } } System.out.println(integers); } public static void quickSort(int start,int end,int[] test) { if (start < end) { int partion = getIndex(start, end, test); quickSort(start, partion, test); quickSort(partion + 1, end, test); } } private static int getIndex(int start, int end, int[] test) { // 基准数据 int tmp = test[start]; while (start < end) { // 当队尾的元素大于等于基准数据时,向前挪动high指针 while (start < end && test[end] >= tmp) { end--; } // 如果队尾元素小于tmp了,需要将其赋值给low test[start] = test[end]; // 当队首元素小于等于tmp时,向前挪动low指针 while (start < end && test[start] <= tmp) { start++; } // 当队首元素大于tmp时,需要将其赋值给high test[end] = test[start]; } // 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置 // 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low] test[start] = tmp; return start; // 返回tmp的正确位置 } }
解法二:
原地算法:
时间复杂度O(n)
空间复杂度O(1)
public class Method3 { public static void main(String[] args) { int[] test = new int[]{2, 3, 1, 0, 2, 5, 3}; System.out.println(answer2(test)); } public static HashSet<Integer> answer2(int[] test) { HashSet<Integer> integers = new HashSet<>(); for (int i = 0; i < test.length; i++) { if (test[i] != i) { while (test[i] != i) { if(test[i] == test[test[i]]){ integers.add(test[i]); break; } int temp = test[i]; test[i] = test[test[i]]; test[temp] = temp; } } } return integers; } }