堆排序
public void heapInsert(int[] arr, int i) {
while (arr[(i - 1) / 2] < arr[i]) {
swap(arr, (i - 1) / 2, i);
i = (i - 1) / 2;
}
}
public void heapify(int[] arr, int i, int size) {
int left = 2 * i + 1;
while (left < size) {
int maxIndex = left + 1 < size && arr[left] < arr[left + 1] ? left + 1 : left;
if (arr[maxIndex] > arr[i]) {
swap(arr, i, maxIndex);
i = maxIndex;
left = 2 * i + 1;
} else {
break;
}
}
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public void sort(int[] arr) {
if (arr.length <= 1) {
return;
}
int i = 0;
while (i < arr.length) {
heapInsert(arr, i++);
}
i = arr.length - 1;
do {
swap(arr, 0, i);
heapify(arr, 0, i--);
} while (i >= 0);
}
数组 arr, 小规模有序,即某个数的位置,排序后的位置不会相差 K的距离
可以利用小根堆实现
public class Heap<T extends Comparator<Integer>> {
int[] arr;
int size;
Comparator<Integer> comparable;
public Heap(int size, Comparator<Integer> comparable) {
arr = new int[size];
this.comparable = comparable;
}
public int getSize() {
return this.size;
}
public boolean isEmpty() {
return size == 0;
}
public void push(int v) {
if (size >= arr.length) {
throw new RuntimeException("满了!");
}
arr[size] = v;
heapInsert();
size++;
}
public int pop() {
if (size == 0) {
throw new RuntimeException("空了!");
}
int v = arr[0];
swrap(arr, 0, --size);
heapify();
return v;
}
private void heapInsert() {
int i = size;
while (comparable.compare(arr[(i - 1) / 2], arr[i]) > 0) {
swrap(arr, (i - 1) / 2, i);
i = (i - 1) / 2;
}
}
private void heapify() {
int i = 0, left = 2 * i + 1;
while (left < size) {
int maxIdx = left + 1 < size && comparable.compare(arr[left], arr[left + 1]) > 0
? left + 1 : left;
if (comparable.compare(arr[i], arr[maxIdx]) > 0) {
swrap(arr, i, maxIdx);
i = maxIdx;
left = 2 * i + 1;
} else {
break;
}
}
}
private void swrap(int[] arr, int i, int i1) {
int temp = arr[i];
arr[i] = arr[i1];
arr[i1] = temp;
}
}
public void sort2(int[] arr, int K) {
Heap<Comparator<Integer>> heap = new Heap<>(K, Comparator.comparingInt(a -> a));
int i = 0, index = 0;
while (i < arr.length) {
heap.push(arr[i++]);
if (heap.getSize() == K) {
arr[index++] = heap.pop();
}
}
while (!heap.isEmpty()) {
arr[index++] = heap.pop();
}
}
给定很多线段,每个线段都有两个数[start, end],表示线段开始位置和结束位置,左右都是闭区间规定∶
1)线段的开始和结束位置一定都是整数值
2)线段重合区域的长度必须>=1
返回线段最多重合区域中,包含了几条线段
public int getMaxRepeat(int[][] arr) {
// 开始位置排序
Arrays.sort(arr, Comparator.comparingInt(a -> a[0]));
// 遍历
int max = 0;
Heap minHeap = new Heap(arr.length, Comparator.comparingInt(a -> a));
for (int i = 0; i < arr.length; i++) {
while (!minHeap.isEmpty() && minHeap.peek() <= arr[i][0]) {
minHeap.pop();
}
minHeap.push(arr[i][1]);
max = Math.max(minHeap.size(), max);
}
return max;
}
public int getMaxRepeatCompare(int[][] arr) {
if (arr.length == 0) {
return 0;
}
Arrays.sort(arr, Comparator.comparingInt(a -> a[0]));
int min = arr[0][0], max = arr[0][1];
for (int i = 0; i < arr.length; i++) {
min = Math.min(arr[i][0], min);
max = Math.max(arr[i][1], max);
}
int total = 0;
for (double s = min + .5; s < max; s += 1) {
int num = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i][0] < s && arr[i][1] > s) {
num++;
}
}
total = Math.max(total, num);
}
return total;
}
public static int[][] lineArray(int maxLength, int maxValue) {
int length = (int) (Math.random() * (maxLength + 1));
int[][] arr = new int[length][2];
for (int i = 0; i < arr.length; i++) {
int end = (int) (Math.random() * (maxValue + 1)) - (int) (Math.random() * (maxValue + 1));
int start = end - (int) (Math.random() * maxValue) - 1;
arr[i][0] = start;
arr[i][1] = end;
}
return arr;
}
public static String print(int[][] arr) {
return "{" + Arrays.stream(arr).map(it ->
"{" + Arrays.stream(it).mapToObj(it2 -> it2 + "").collect(Collectors.joining(",")) + "}"
).collect(Collectors.joining(",")) + "}";
}
@Test
public void test12() {
for (int i = 0; i < 1000; i++) {
int[][] arr = lineArray(100, 100);
int a1 = getMaxRepeat(arr);
int a2 = getMaxRepeatCompare(arr);
if (a1 != a2) {
System.out.printf("%s, a1: %d, a2: %d", print(arr), a1, a2);
return;
}
}
}