题目一
二分法
在有序数组中查找num,返回num的索引
static int binaryfind(int[] arr, int num) {
int pre = 0;
int aft = arr.length - 1;
while (pre <= aft) {
int mid = (pre + aft) / 2;
if (arr[mid] < num) {
pre = mid + 1;
} else if (arr[mid] > num) {
aft = mid - 1;
} else {
return mid;
}
}
return -1;
}
题目二
二分法
找到有序数组查找大于等于num的最左面的索引
static int binary(int[] arr, int num) {
if (arr == null || arr.length == 0) {
return -1;
}
int pre = 0;
int aft = arr.length - 1;
int index = -1;
while (pre <= aft) {
int mid = (pre + aft) / 2;
if (arr[mid] >= num) {
index = mid;
aft = mid - 1;
}
if (arr[mid] < num) {
pre = mid + 1;
}
}
return index;
}
题目三
二分法
在一个相邻的数都不相等的数组中,找到任意一个局部最小值的位置
static int oneMinIndex(int[] arr) {
if (arr == null || arr.length == 0) {
return -1;
}
int n = arr.length;
if (n == 1) {
return 0;
}
if(arr[0]<arr[1]){
return 0;
}
if(arr[n-2]>arr[n-1]){
return n-1;
}
int pre = 0;
int aft = n - 1;
while (pre <= aft) {
int mid = (pre + aft) / 2;
if (arr[mid] < arr[mid + 1]) {
if (arr[mid] < arr[mid - 1]) {
return mid;
}
aft = mid - 1;
} else {
pre = mid + 1;
}
}
return -1;
}
时间复杂度
常数操作:一个操作时间和传入数据无关的操作叫常数操作
时间复杂度:当数据量非常大时,完成操作需要的复杂度
选择、冒泡、插入排序的时间复杂度都是o(n^2)
常见时间复杂度列表
o(1)<o(logN)<o(N)<o(N*logN)<o(N^2)<o(N^3)<o(N^k)<o(2^N)<o(3^N)<o(k^N)<o(N!)
动态数组
动态数组:动态数组可以根据传入元素的数量完成自动扩容
例如ArrayList的使用和扩容
动态数组的时间复杂度是o(N),但是某一次扩容时,所需时间为o(1)
按值传递和按引用传递
默认情况下,Java中默认的数据类型是按值传递,自定义类型是按引用传递,每一个元素都是包含地址,一个地址值是八个字节
public static class Node {
public int value;
public Node(int v) {
value = v;
}
}
HashMap<Integer, String> map2 = new HashMap<>();
map2.put(1234567, "我是1234567");
Integer a = 1234567;
Integer b = 1234567;
System.out.println(a == b);
System.out.println(map2.containsKey(a));//true
System.out.println(map2.containsKey(b));//true
Node node1 = new Node(1);
Node node2 = new Node(1);
HashMap<Node, String> map3 = new HashMap<>();
map3.put(node1, "我进来了!");
System.out.println(map3.containsKey(node1));//true
System.out.println(map3.containsKey(node2));//flase
哈希表和有序表
哈希(Hash)表无序,时间复杂度为o(1)
有序(Tree)表有序,时间复杂度为o(logN)
import java.util.HashMap;
import java.util.TreeMap;
public class Code05_HashMapTreeMap {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
map.put("zuochengyun", "我是左程云");
System.out.println(map.containsKey("zuochengyun"));
System.out.println(map.containsKey("zuo"));
System.out.println(map.get("zuochengyun"));
map.put("zuochengyun", "他是左程云");
System.out.println(map.get("zuochengyun"));
// map.remove("zuochengyun");
// System.out.println(map.containsKey("zuochengyun"));
// System.out.println(map.get("zuochengyun"));
String test1 = "zuochengyun";
String test2 = "zuochengyun";
System.out.println(map.containsKey(test1));//true
System.out.println(map.containsKey(test2));//true
System.out.println("===================");
TreeMap<Integer, String> treeMap1 = new TreeMap<>();
treeMap1.put(3, "我是3");
treeMap1.put(0, "我是3");
treeMap1.put(7, "我是3");
treeMap1.put(2, "我是3");
treeMap1.put(5, "我是3");
treeMap1.put(9, "我是3");
System.out.println(treeMap1.containsKey(7));
System.out.println(treeMap1.containsKey(6));
System.out.println(treeMap1.get(3));
treeMap1.put(3, "他是3");
System.out.println(treeMap1.get(3));
treeMap1.remove(3);
System.out.println(treeMap1.get(3));
//获取第一个(最小的)Key
System.out.println(treeMap1.firstKey());
//获取最后一个(最大的)Key
System.out.println(treeMap1.lastKey());
// <=5 离5最近的key告诉我
System.out.println(treeMap1.floorKey(5));
// <=6 离6最近的key告诉我
System.out.println(treeMap1.floorKey(6));
// >=5 离5最近的key告诉我
System.out.println(treeMap1.ceilingKey(5));
// >=6 离6最近的key告诉我
System.out.println(treeMap1.ceilingKey(6));
}
}