- 如何在10000个数中找到第10大的数?
使用快排。每趟快排会使一个数放置在最终的位置,并且将序列分成两部分,左边全部小于该基准元素,右边全部大于基准元素,如果该位置大于10,那就递归左边,否则递归右边,直到某趟基准元素的位置等于10,则该元素即为所求。
思想类似二分查找某个元素,不断缩小搜索范围。假设共个数,找第大的数,每趟快排时间复杂度为,共进行趟,总共的时间复杂度为,和无关,找任意第大的数都是这样。
使用冒泡排序。当k很小时,冒泡排序更好,冒k趟就可以了,时间复杂度
- 如何在10000个数中找到前10大的数?
使用堆排。先用前10个数建立一个小根堆,从第11个数开始遍历,依次和堆顶的数比较,如果比堆顶元素大,则替换掉堆顶元素,接着调整堆,使之保持小根堆,如果比堆顶元素小,则继续遍历下一个数。遍历完所有数,最终的小根堆里的数即为所求。
建堆,(应该有常数系数1/2),后面n-k次,但不一定每次都需要调整堆,具体调整多少次不好计算,每次调整,总的时间复杂度小于,即
- 反人类的
Arrays.asList()
Arrays.asList()用于将数组转化为集合,首先它接收的是包装类型的数组,不接收基本数据类型的数组:
Integer[] myArray = {1, 2, 3};
List myList = Arrays.asList(myArray);
如果元素数量不大,也可以直接写里面:
List myList = Arrays.asList(1, 2, 3);
其次它返回的是ArrayList的内部类,基本不能直接用,需要再转为ArrayList才可以:
Integer[] myArray = {1, 2, 3};
List myList = new ArrayList<>(Arrays.asList(myArray));
此外,接口List的方法toArray()也挺反人类的,它用于将集合转化为数组,它需要一个仅表示元素类型的0空间数组作为参数,它难道不能自己识别自己的类型?
List myList = new ArrayList<>(Arrays.asList("aa","bb"));
myArray=myList.toArray(new String[0]);
- 日常代码
Scanner scanner = new Scanner(System.in);
String a = scanner.nextLine();
// 字符串分割
String str = "1 2 3 4";
String[] arr = str.split(" ");
// 字符串数组转int数组
int[] array = Arrays.stream(arr).mapToInt(Integer::parseInt).toArray();
// int数组转Integer数组
int[] nums = {1,2,3,4,5,6};
Integer newNums[] = Arrays.stream(nums).boxed().toArray(Integer[]::new);
// Integer数组转int数组
int[] arr2 = Arrays.stream(integers1).mapToInt(Integer::valueOf).toArray();
// int数组转Integer集合
List<Integer> list1 = Arrays.stream(data).boxed().collect(Collectors.toList());
// 字符串数组用连接符拼接
String[] strArray = { "How", "To", "Do", "In", "Java" };
String joinedString = String.join(", ", strArray);
System.out.println(joinedString);
// 将字符串解析为对应的数字基本类型 parseXxx()
int Integer.parseInt("12")
float Float.parseFloat("1.2")
double Double.parseDouble("1.2")
// 将Number转化为对应的基本类型 xxxValue(),该方法是抽象类Number的,Integer、Long、Byte、Double、Float、Short都是Number的子类
int integer.intValue() // 自动拆箱即调用该方法
float integer.floatValue()
// 从右向左转换 valueOf(),String、Integer、Double、Float都有该方法
String s1 = String.valueOf(12);
String s1 = String.valueOf(12.34);
Integer x =Integer.valueOf(9); // 自动装箱即调用该方法
Double c = Double.valueOf(5);
Float a = Float.valueOf("80");
- 糟糕的
binarySearch方法
Arrays.binarySearch()和Collections.binarySearch()都实现了二分查找,前者是普通数组,后者是集合,即对实现了Comparable接口的对象都可以
int a[] = new int[] {1, 3, 4, 6, 8, 9};
int x1 = Arrays.binarySearch(a, 5); // -4
int x2 = Arrays.binarySearch(a, 4); // 2
int x3 = Arrays.binarySearch(a, 0); // -1
int x4 = Arrays.binarySearch(a, 10); // -7
- 对于查找存在的元素,且元素唯一,则正确返回其对应位置,从0开始
- 查找不存在的元素,则返回一个负数,其绝对值是该元素应该插入的位置,从1开始
- 如果查找的元素存在,但不唯一,即数组又重复的多个该元素,则返回的位置不确定
ps:
Python中的二分查找就更好,对于查找的元素存在,且重复的情况,bisect_left()返回重复元素的左端点的位置,bisect_right()返回重复元素的右端点的位置+1,即左闭右开区间
如果查找存在的元素,且元素唯一,bisect_left()返回该元素的位置,bisect_right()返回该元素位置+1,其实和左闭右开一样
如果查找不存在的元素,则bisect_left()和bisect_right()都返回该元素应该插入的位置