算法要求:需要去重,和排序。规模在1000;
1.A方法,直接对数据结构进行操作不使用API
// 关于去重,直接遍历去重,时间复杂度O(n^2),空间复杂度0// 桶排序方法去重,这样既可以去重,顺便已经将数据排序,完美的符合了要求。整个程序的时间复杂度O(1),空间复杂度N
2.B方法,使用JavaAPI处理问题
// API解决问题,选择容器就可以了。
//3.比较俩种方法的执行效率。范围:题目范围的上限
import java.util.ArrayList;
//啊哈算法:小哼买书
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
//算法要求:需要去重,和排序。规模在1000;
//1.算法层面
// 关于去重,直接遍历去重,时间复杂度O(n^2),空间复杂度0
// 桶排序方法去重,这样既可以去重,顺便已经将数据排序,完美的符合了要求。整个程序的时间复杂度O(1),空间复杂度N
//2.java层面
// API解决问题,选择容器就可以了。
//3.比较俩种方法的执行效率,范围:题目范围的上限
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
// int[] ISBN = readin();
Random random = new Random();
int[] arr = new int[999];
for (int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(1000);
}
// int[] res = operationA(arr);
// System.out.println(res.length);
//输出格式自己可调,我太懒了,就这么写了
// System.out.println((Arrays.toString(res).replaceAll(",", " ").substring(1,Arrays.toString(res).replaceAll(",", " ").length()-1)));
ArrayList<Integer> isbn2 = operationB(arr);
System.out.println(isbn2.size());
// //输出格式自己可调,我太懒了,就这么写了
// System.out.println((isbn2.toString().replaceAll(",", " ").substring(1,isbn2.toString().replaceAll(",", " ").length()-1)));
}
private static ArrayList<Integer> operationB(int[] iSBN) {
// TODO Auto-generated method stub
//创建Set的容器
long startTime = System.nanoTime();
HashSet<Integer> isbn = new HashSet<>();
for (int i = 0; i < iSBN.length; i++) {
isbn.add(iSBN[i]);
}
//Collections.sort可以对list进行排序,所以将hash的去重后的数据放入list中。进行排序
ArrayList<Integer> list = new ArrayList<>(isbn);
Collections.sort(list);
long consumingTime = System.nanoTime() - startTime;
System.out.println(consumingTime);
return list;
}
private static int[] operationA(int[] ISBN) {
// TODO Auto-generated method stu
//计算方法的执行时间,用来求证3
long startTime = System.nanoTime();
//创建桶
int[] bucket = new int[1000];
//进行排序
for (int i = 0; i < ISBN.length; i++) {
bucket[ISBN[i]] = 1;
}
//将排好序的数据放回原数组, 考虑到去重后剩余的情况,最好应该返回一个新数组,不用之前的数组。以免之后的操作繁琐。
// int temp = 0 ;
// for (int i = 0; i < bucket.length; i++) {
// if(bucket[i] == 1)
// ISBN[temp++] = i;
// }
//用来确定新数组的大小
int num = 0;
for (int i = 0; i < bucket.length; i++) {
if(bucket[i] == 1)
num++;
}
int[] list = new int[num];
//num现在用来控制新数组的下标
num = 0;
for (int i = 0; i < bucket.length; i++) {
if(bucket[i] == 1)
list[num++] = i;
}
long consumingTime = System.nanoTime() - startTime;
System.out.println(consumingTime);
return list;
}
private static int[] readin() {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc.nextLine());
int[] arr = new int[n];
String[] str = sc.nextLine().split(" ");
for (int i = 0; i < arr.length; i++) {
arr[i] = Integer.parseInt(str[i]);
}
return arr;
}
}
最后对问题三进行了测试:
结果证明在普通的测试用例情况下:不用方法A和方法B运行时间相差了1个数量级
A运行时间:29013 30720 保持在了5位数
B运行时间:442596 460231 保持在了6位数
结果证明在极限的测试用例情况下:不用方法A和方法B运行时间相差了2个数量级
A运行时间:51200 49494 仍然保持在5位数
B运行时间:442596 460231 保持在了7位数
代码很糟糕,且看且珍惜吧。自己用来复盘的时候用。说实话自己都不想看自己的代码了,写的太差劲。最后的结论很有可能不太准确,因为可能是我自己对api运用不正确导致浪费导致的!