publicstaticvoidmain(String[] args){ GetMinStack<Integer> stack = new GetMinStack<>(); int[] data = {8, 4, 2, 6, 1, 9, -1, 3}; for (int i: data) { stack.push(i); Optional<Integer> min = stack.getMin(); System.out.println("push " + i + ", min: " + min.get() + ", stack" + stack + ", minStack: " + stack.getMinStack()); }
while (!stack.empty()) { int i = stack.pop(); Optional<Integer> min = stack.getMin(); if (min.isPresent()) { System.out.println("pop " + i + ", min: " + min.get() + ", stack" + stack + ", minStack: " + stack.getMinStack()); } else { System.out.println("pop " + i + ", stack is empty"); } } }
publicGetMinStack(){ minStack = new Stack<>(); }
@Override publicsynchronized E pop(){ E item = super.pop(); E min = minStack.peek(); // 如果出栈的元素跟最小栈顶元素相等,则最小栈顶也出栈 if (min == item) { minStack.pop(); } return item; }
@Override public E push(E item){ if (!minStack.empty()) { E min = minStack.peek(); // 如果栈不空,看最小栈顶与入栈元素哪个小; // 一样大或者入栈元素小,则该元素入最小栈; // 否则不做任何操作 if (min.compareTo(item) >= 0) { minStack.push(item); } } else { // 栈空就直接入栈 minStack.push(item); } returnsuper.push(item); }
public Optional<E> getMin(){ if (empty()) { return Optional.empty(); } else { return Optional.of(minStack.peek()); } }
public Collection<E> getMinStack(){ return Collections.unmodifiableCollection(this.minStack); } }
public Optional<E> poll(){ if (popStack.empty()) { while (!pushStack.empty()) { popStack.push(pushStack.pop()); } if (popStack.empty()) { return Optional.empty(); } }
StackQueue{pushStack=[hello, world, how, are, you]=>, popStack=[]=>} hello world how are you StackQueue{pushStack=[]=>, popStack=[]=>} StackQueue{pushStack=[hello, world, how, are, you]=>, popStack=[]=>} StackQueue{pushStack=[hello, world, how, are, you]=>, popStack=[you, are, how, world]=>} hello world how are you hello world how are you StackQueue{pushStack=[]=>, popStack=[]=>}
public Node setNext(Node<T> next){ this.next = next; returnthis; }
public Node getNext(){ returnthis.next; }
public T getValue(){ returnthis.value; }
public Node<T> reverse(){ Node<T> head = this; Node<T> pre = null;
while (head != null) { Node<T> next = head.getNext();
head.setNext(pre); pre = head;
head = next; }
return pre; }
@Override public String toString(){ StringBuilder sb = new StringBuilder(); Node<T> cur = this; while (cur != null) { sb.append(cur.getValue()); sb.append(" -> "); cur = cur.getNext(); } sb.append("null"); return sb.toString(); } }
输出内容:
1 2 3
build: hello -> world -> are -> you -> ok -> null reversed: ok -> you -> are -> world -> hello -> null origin: hello -> world -> are -> you -> ok -> null
publicstatic <T> DoubleNode<T> build(T ...values){ DoubleNode<T> list = null; DoubleNode<T> cur = null;
for (T value: values) { if (cur == null) { cur = new DoubleNode<>(value); list = cur; } else { DoubleNode<T> node = new DoubleNode<>(value); node.setPrevious(cur); cur.setNext(node); cur = cur.getNext(); } }
public DoubleNode<T> setNext(DoubleNode<T> next){ this.next = next; returnthis; }
public DoubleNode<T> getNext(){ returnthis.next; }
public T getValue(){ returnthis.value; }
public DoubleNode<T> getTailNode(){ DoubleNode<T> cur = this; while (cur.getNext() != null) { cur = cur.getNext(); } return cur; }
public DoubleNode<T> getPrevious(){ returnthis.previous; }
public DoubleNode<T> setPrevious(DoubleNode<T> previous){ this.previous = previous; returnthis; }
public DoubleNode<T> reverse(){ DoubleNode<T> head = this; DoubleNode<T> pre = null;
while (head != null) { DoubleNode<T> next = head.getNext();
// 其他都跟单链表一样,指针多设置一个 head.setNext(pre); head.setPrevious(next); pre = head;
head = next; }
return pre; }
@Override public String toString(){ StringBuilder sb = new StringBuilder(); DoubleNode<T> cur = this; while (cur != null) { sb.append(cur.getValue()); sb.append(" -> "); cur = cur.getNext(); } sb.append("null"); return sb.toString(); }
public String toStringBack(){ StringBuilder sb = new StringBuilder("null"); DoubleNode<T> cur = this; while (cur != null) { sb.append(" <- "); sb.append(cur.getValue()); cur = cur.getPrevious(); } return sb.toString(); } }
输出内容:
1 2 3 4
build: hello -> world -> are -> you -> ok -> null reversed: ok -> you -> are -> world -> hello -> null origin: hello -> world -> are -> you -> ok -> null back: null <- ok <- you <- are <- world <- hello
int[] getOddTimesNumbers(int[] array) { int xor = 0; for (int i: array) { xor ^= i; }
// xor == a ^ b // 因为 a != b (两种数),所以 a ^ b != 0,则必然存在为 1 的二进制位 // 不妨就使用最后一个 1,即 int one = xor & (~xor + 1); // 假设这个 1 在第 N 位 int a = 0; for (int i: array) { // 将数组分为两类:1. N 位上为 1 的;2. N 位上为 0 的。 // a 和 b 一定分别属于这两类,不会同属一类,因为 a ^ b 的 N 位是 1 // 这里只把第 1 类异或起来,得到一种数 if ((i & one) != 0) { a ^= i; } }
// 用之前得到的这种数异或 xor,得到另一种 returnnewint[]{a, a ^ xor}; }
Java 实现(函数式)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
int[] getOddTimesNumbers(int[] array) { int xor = Arrays.stream(array).reduce(0, (a, b) -> a ^ b);
int one = xor & (~xor + 1); int a = Arrays.stream(array).reduce(0, (v1, v2) -> { if ((v2 & one) != 0) { return v1 ^ v2; } else { return v1; } });
returnnewint[] {a, xor ^ a}; }
Rust 实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
fnget_odd_times_numbers(array: &[i32]) -> (i32, i32) { letmut xor = 0; for i in array { xor ^= *i; }
let one = xor & (!xor + 1); letmut a = 0; for i in array { if one & *i != 0 { a ^= *i; } }
(a, xor ^ a) }
Rust 实现(函数式)
1 2 3 4 5 6 7 8 9 10 11
fnget_odd_times_numbers(array: &[i32]) -> (i32, i32) { let xor = array.iter().fold(0, |a, b| a ^ *b);
let one = xor & (!xor + 1); let a = array .iter() .fold(0, |a, b| if one & b != 0 { a ^ *b } else { a });
#[test] fntest_get_odd_times_numbers() { use rand::prelude::*;
letmut rng = thread_rng();
for _ in0..1000 { letmut vec = Vec::new(); let odd_number_a = rng.gen_range(0..5); let odd_number_b = loop { let b = rng.gen_range(0..5); if b != odd_number_a { break b; } else { continue; } }; for i in0..5 { let times: usize = rng.gen_range(1..3) * 2 + if i == odd_number_a || i == odd_number_b { 1 } else { 0 }; for _ in0..times { vec.push(i); } } vec.shuffle(&mut rng);
let get = get_odd_times_numbers(&vec); assert!(get == (odd_number_a, odd_number_b) || get == (odd_number_b, odd_number_a)); } }
5. 计算某个数为 1 的二进制位数
例如:
1
0b00101100 --> 3
Java 实现
1 2 3 4 5 6 7 8 9 10 11 12
intcountOnes(int a){ int count = 0;
while (a != 0) { count += 1; int one = a & (~a + 1); a ^= one; // 把这个 1 给去掉 }
letmut left = 1; letmut right = len - 2; while left < right { let mid = mid(left, right); if array[mid] > array[mid - 1] { right = mid - 1; } elseif array[mid] > array[mid + 1] { left = mid + 1; } else { returnSome(mid); } }
Some(left) }
/// 计算两个无符号值的中间值 fnmid<T: Ord + Div<Output = T> + Add<Output = T> + Copy + Sub<Output = T> + From<u8>>( v1: T, v2: T, ) -> T { match v1.cmp(&v2) { Ordering::Less => { let v = v2 - v1; v1 + v / T::from(2u8) } Ordering::Equal => v1, Ordering::Greater => { let v = v1 - v2; v2 + v / T::from(2u8) } } }
/// 判断一个索引是否为局部最小值的索引 fnis_local_minimum(array: &[i32], index: usize) -> bool { let len = array.len(); if len == 0 { returnfalse; } if len == 1 { return index == 0; }
let range = 0..len; if !range.contains(&index) { returnfalse; }
// 1. `0` 位置如果比 `1` 位置数小,则 `0` 位置为局部最小; if index == 0 && array[0] < array[1] { returntrue; }
// 2. `N-1` 位置如果比 `N-2` 位置数小,则 `N-1` 位置为局部最小; if index == len - 1 && array[len - 1] < array[len - 2] { returntrue; }
“When using Futures, error messages are inscrutable.” “当使用 Future 时,错误信息难以理解。” “Having to use RefCell or clone everything for each future leads to overcomplicated code that makes me wish Rust had garbage collection.” “不得不使用 RefCell 以及为每个 future 克隆所有它需要的值产生了过于复杂的代码,这让我开始期待 Rust 能具备垃圾回收功能了。”