早上大概郁闷了很长一段时间,既埋怨自己高不成低不就,也吐槽那些觉得我太卢瑟不鸟我的同学。曾几何时,我还是不弱的一个学生,无论是高考还是GPA,至少是高于平均水平的,现在呢?比不上大部分人。进而吐槽自己踏步不前,而别人都在努力,当然比你进步得快。
埋怨完了之后花了些时间把最新三道leetcode题目做完。
======================================================
这道题目一开始想用min heap,但是维持min heap需要lg(n)的时间复杂度,Parker大神说:你有没有注意到,只有每次push一个更小的int的时候,min才会更新...智商被碾压了吧。代码很简单,但是有个bug要注意,如果连续push一样的整数,min的stack也要push同样的最小值,因为我的代码会检查当前值是否和min栈顶的整数一样,一样就pop,如果只记住一个整数,那么pop第二个相同的整数就会有runtime error。
class MinStack {
// push a pair <current, min>
private Stack<Integer> stk = new Stack<Integer>();
private Stack<Integer> min = new Stack<Integer>();
public void push(int x) {
stk.push(x);
if (min.empty() || min.peek() >= x) {
min.push(x);
}
}
public void pop() {
int x = stk.pop();
if (!min.empty() && min.peek() == x) {
min.pop();
}
}
public int top() {
return stk.peek();
}
public int getMin() {
return min.peek();
}
}
======================================================
跟search in rotated sorted array很像,其实也是二分搜索(binary search)。
如果num[start] < num[end]肯定是没有rotate过的那一段,返回num[start]就可以了,否则肯定是rotate的那一段,那么找中点,比较num[start]和num[mid],还是用前面那个准则就可以。当然这里要注意一个bug,就是num[start]可能和num[mid]相同,这个时候是只剩两个元素的情况:mid == start。
代码如下:
public class Solution {
public int findMin(int[] num) {
int start = 0;
int end = num.length - 1;
while (start < end) {
if (num[start] < num[end]) {
return num[start];
} else {
int mid = (start + end) / 2;
if (num[start] <= num[mid]) {
start = mid + 1;
} else {
end = mid;
}
}
}
return num[start];
}
}
======================================================
至于有duplicate情况Find Minimum in Rotated Sorted Array II,其实就多增加对相等的判断。就是num[start] == num[end]可能这一段也包含转折点!如果取中点之后无法排除[start, mid]或者[mid+1, end]这段区间,那么就start++就好。
代码如下:
public class Solution {
public int findMin(int[] num) {
int start = 0;
int end = num.length - 1;
while (start < end) {
if (num[start] < num[end]) {
return num[start];
} else {
int mid = (start + end) / 2;
if (num[start] < num[mid]) start = mid + 1;
else if (num[start] > num[mid]) end = mid;
else start++;
}
}
return num[start];
}
}