Leetcode - "Min stack" "Find Minimum in Rotated sorted Array"

早上大概郁闷了很长一段时间,既埋怨自己高不成低不就,也吐槽那些觉得我太卢瑟不鸟我的同学。曾几何时,我还是不弱的一个学生,无论是高考还是GPA,至少是高于平均水平的,现在呢?比不上大部分人。进而吐槽自己踏步不前,而别人都在努力,当然比你进步得快。

埋怨完了之后花了些时间把最新三道leetcode题目做完。

======================================================

min stack

这道题目一开始想用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();
    }
}


======================================================

Find Minimum in Rotated sorted Array I

跟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];
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值