初级三
综合排序
如果数组长度很长,在工程上,先进行判断里面装的基础类型还是定义的class,基础类型用快排,如果是根据student的某一个字段比较,则用归并排序来排,如果数组长度很短,用插入排序,(长度小于60)虽然复杂度是O(n^2),但是在样本量极小的情况劣势下表现不出来,反而常数项很低,导致在小样本的情况下插入会飞快,
大数组先分治,递归的部分一旦小于60直接插排。基础类型不需要关心前后顺序,无差异,所以用快排,如果student先按照分数排序,再按照班级排序,此时相同班级的个体可能不一样,是有差别的,所以用归并(具有稳定性)。
排序问题补充
partition过程是时间复杂度O(n),空间复杂度O(1);不能保证稳定性
比较器使用
桶排序(具体实现为记数排序):已知数组范围,准备一个数组,遍历一个数组,重构一个数组,时间复杂度O(N),有瓶颈,不基于比较的排序总有瓶颈,基于数据状况本身,
n个数,准备n+1个桶,只统计进入每一个桶的最小值和最大值,还有一个bool表示这个桶里面进没进来过数,对于数组中每一个数,进桶更改最小值,最大值,和bool。从1号桶开始,遍历每一个桶,空桶跳过,非空桶用该桶的最小值和前一个非空桶的最大值比较,每一个差值最终一定有一个是最后的解。
设计空桶的分析方式的目的是来否定最大差值一定不来自一个桶内部,但是答案不一定来自空桶两侧非空桶,比如 19 空 30 49 差值分别是11和19
找寻排好序的数组中相邻数的最大差值
public class MaxGap {
public static int getMaxGap(int[] nums) {
if (nums == null || nums.length < 2) {
return 0;
}
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
max = Math.max(max, nums[i]);
min = Math.min(min, nums[i]);
}
if (max == min) {
return 0;
}
boolean[] hasNumber = new boolean[nums.length + 1];
int[] maxValue = new int[nums.length + 1];
int[] minValue = new int[nums.length + 1];
maxValue[nums.length] = max;
minValue[0] = min;
for (int i = 0; i < nums.length; i++) {
//放到哪个桶
int bucketId = getBucketId(nums[i], min, max, nums.length);
// if (hasNumber[bucketId]) {
// if (maxValue[bucketId] < nums[i]) {
// maxValue[bucketId] = nums[i];
// }
// if (minValue[bucketId] > nums[i]) {
// minValue[bucketId] = nums[i];
// }
// } else {
// minValue[bucketId] = nums[i];
// maxValue[bucketId] = nums[i];
//
// hasNumber[bucketId] = true;
// }
maxValue[bucketId] = hasNumber[bucketId] ? Math.max(maxValue[bucketId], nums[i]) : nums[i];
minValue[bucketId] = hasNumber[bucketId] ? Math.min(minValue[bucketId], nums[i]) : nums[i];
hasNumber[bucketId] = true;
}
int result = 0;
int lastMax = nums[0];
for (int i = 0; i < hasNumber.length; i++) {
if (hasNumber[i]) {
result = Math.max(result, (minValue[i] - lastMax));
lastMax = maxValue[i];
}
}
return result;
}
private static int getBucketId(long num, long min, long max, long length) {
//用long防止相乘溢出
return (int) ((num - min) * length / (max - min));
}
}
数组模拟栈
public class ArrayToStack {
static class ArrayStack {
int[] arrayStack;
int size;
public ArrayStack(int length) {
if (length < 0) {
throw new IllegalArgumentException("栈空");
}
arrayStack = new int[length];
size = 0;
}
public int pop() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("没有数据了");
}
return arrayStack[--size];
}
public int peek() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("没有数据了");
}
return arrayStack[size - 1];
}
public void push(int num) {
if (size == arrayStack.length) {
throw new ArrayIndexOutOfBoundsException("栈满了");
}
arrayStack[size++] = num;
}
}
public static void main(String[] args) {
ArrayStack arrayStack = new ArrayStack(3);
arrayStack.push(10);
arrayStack.push(11);
arrayStack.push(12);
// int peek = arrayStack.peek();
// System.out.println("peek = " + peek);
arrayStack.push(1);
while (arrayStack.size != 0) {
System.out.println(arrayStack.pop());
}
// int pop = arrayStack.pop();
// System.out.println("pop = " + pop);
}
}
数组模拟队列
public class ArrayToQueue {
static class ArrayQueue {
int[] arrayQueue;
//要出列的位置
int start;
//要入列的位置
int end;
//队列中元素个数
int size;
public ArrayQueue(int length) {
if (length < 0) {
throw new IllegalArgumentException("栈空");
}
arrayQueue = new int[length];
start = 0;
end = 0;
size = 0;
}
public int poll() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("队列为空");
}
size--;
int result = arrayQueue[start];
start = start == arrayQueue.length - 1 ? 0 : start + 1;
return result;
}
public int peek() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("队列为空");
}
return arrayQueue[start];
}
public void push(int num) {
if (size == arrayQueue.length) {
throw new ArrayIndexOutOfBoundsException("队列满了");
}
size++;
arrayQueue[end] = num;
end = end == arrayQueue.length - 1 ? 0 : end + 1;
}
}
public static void main(String[] args) {
ArrayQueue arrayQueue = new ArrayQueue(3);
arrayQueue.push(10);
int peek = arrayQueue.peek();
System.out.println("peek = " + peek);
int poll = arrayQueue.poll();
System.out.println("poll = " + poll);
arrayQueue.push(10);
arrayQueue.push(1);
arrayQueue.push(13434);
while (arrayQueue.size != 0) {
System.out.println(arrayQueue.poll());
}
}
}
栈模拟队列
public class TwoStacksQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
public TwoStacksQueue() {
stack1 = new Stack();
stack2 = new Stack();
}
public void add(int num) {
stack1.push(num);
stack1Tostack2();
}
public int peek() {
if (stack2.isEmpty() && stack1.isEmpty()) {
throw new ArrayIndexOutOfBoundsException("队列已空");
}
stack1Tostack2();
return stack2.peek();
}
public int poll() {
if (stack2.isEmpty() && stack1.isEmpty()) {
throw new ArrayIndexOutOfBoundsException("队列已空");
}
stack1Tostack2();
return stack2.pop();
}
private void stack1Tostack2() {
if (!stack1.isEmpty() && stack2.isEmpty()) {
while (!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}
}
public static void main(String[] args) {
TwoStacksQueue queue = new TwoStacksQueue();
queue.add(10);
queue.add(11);
queue.add(12);
queue.add(13);
int peek = queue.peek();
System.out.println("peek = " + peek);
int poll = queue.poll();
System.out.println("poll = " + poll);
for (int i = 0; i < 10; i++) {
System.out.println("queue.poll() = " + queue.poll());
}
}
}
队列模拟栈
public class TwoQueuesStack {
LinkedList<Integer> listData;
LinkedList<Integer> listHelp;
int size;
public TwoQueuesStack(int i) {
listData = new LinkedList();
listHelp = new LinkedList();
size = 0;
}
public void push(int num) {
listData.add(num);
}
public int peek() {
if (listData.isEmpty()) {
throw new RuntimeException("栈中没元素了");
}
while (listData.size() > 1) {
listHelp.add(listData.poll());
}
Integer poll = listData.poll();
listHelp.add(poll);
swap();
return poll;
}
public int pop() {
if (listData.isEmpty()) {
throw new RuntimeException("栈中没元素了");
}
while (listData.size() > 1) {
listHelp.add(listData.poll());
}
int poll = listData.poll();
swap();
return poll;
}
private void swap() {
LinkedList<Integer> list = listData;
listData = listHelp;
listHelp = list;
}
public static void main(String[] args) {
TwoQueuesStack stack = new TwoQueuesStack(3);
stack.push(1);
stack.push(2);
stack.push(3);
int peek = stack.peek();
System.out.println("peek = " + peek);
for (int i = 0; i < 3; i++) {
System.out.println(stack.pop());
}
}
}
栈中最小值(时间复杂度O(1))
public class GetMin {
Stack<Integer> stack = new Stack<>();
Stack<Integer> stackMin = new Stack<>();
public void push(int num) {
stack.push(num);
stackMin.push(stackMin.size() == 0 ? num : Math.min(stackMin.peek(), num));
}
public int pop() {
if (stack.size()==0){
throw new RuntimeException("栈已空");
}
stackMin.pop();
return stack.pop();
}
public int getMin() {
if (stackMin.size() == 0) {
throw new RuntimeException("栈已空");
}
return stackMin.peek();
}
public int peek() {
return stack.peek();
}
public static void main(String[] args) {
GetMin stack = new GetMin();
stack.push(1);
stack.push(6);
stack.push(-1);
stack.push(43);
stack.push(34);
stack.pop();
stack.pop();
stack.pop();
stack.pop();
stack.pop();
stack.pop();
stack.pop();
int min = stack.getMin();
System.out.println("min = " + min);
}
}