Leetcode739 Daily Temperatures Java实现

首先想到暴力解法,方法1:

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int[] results = new int[temperatures.length];
        for(int i=0;i<temperatures.length;i++) {
            int days = 0;
            for(int j=i+1;j<temperatures.length;j++) {
                days++;
                if(temperatures[j]>temperatures[i]) {results[i]=days;break;}
            }
        }
        return results;
    }
}

效果可以说是十分的差了,然后想办法改进,发现可以使用map存储没有处理的数,在一次遍历中完成,但是最坏的情况下时间复杂度其实并没有降低,最终实测由于set相关操作较慢,还超时了,但是有些东西还是有价值的,故记录一下,方法2(并不能AC):

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int[] result = new int[temperatures.length];
        HashMap<Integer,Integer> map = new HashMap<>();
        map.put(0, temperatures[0]);
        Set<Map.Entry<Integer, Integer>> set = map.entrySet();
        for(int i=1;i<temperatures.length;i++) {
//            for(int k:set) {        //java.util.ConcurrentModificationException因为之后更改了迭代条件set
//            if(temperatures[i]>k) {
//                int v = map.get(k);
//                result[v]=i-v;
//                map.remove(k);
//            }
//        }
        //ConcurrentModificationException Solution1:用Iterator的remove;Solution2:用/ConcurrentHashMap(貌似叫这个名字)
            Iterator<Map.Entry<Integer, Integer>> iter = set.iterator();
            while(iter.hasNext()) {
                Map.Entry<Integer, Integer> n = iter.next();
                int v = n.getValue();
                if(temperatures[i]>v) {
                    int k = n.getKey();
                    result[k] = i-k;
                    iter.remove();
                }
            }
            map.put(i, temperatures[i]);
        }
        return result;
    }
}

 这个超时搞得我很懵逼,于是学习一下solution好了。

然后学习到,其实我的方法2思路是正确的,只不过实施的时候挑了HashMap,存储了本来就在temperatures数组里存储而且可以随机存取的数据了,导致效率低下,用Stack,Deque等数据结构存储index即可,于是方法3,使用Set:

    public int[] dailyTemperatures(int[] T) {
        int[] result = new int[T.length];
        HashSet<Integer> set = new HashSet<>();
        for(int i=0;i<T.length;i++) {
            Iterator<Integer> iter = set.iterator();
            while(iter.hasNext()) {
                int index = iter.next();
                if(T[i]>T[index]) {
                    result[index]=i-index;
                    iter.remove();
                }
            }
            set.add(i);
        }
        return result;
    }

依旧超时,看来使用iterator的都会超时?

试试Stack,方法4:

首先

    public int[] dailyTemperaturesv4a(int[] T) {
        int[] result = new int[T.length];
        Stack<Integer> stack = new Stack<>();
        for(int i=0;i<T.length;i++) {
            while(!stack.empty()) {
                int index = stack.peek();
                if(T[i]>T[index]) {
                    result[index]=i-index;
                    stack.pop();
                }
            }
            stack.push(i);
        }
        return result;
    }

第一条就超时,然后参考别人的答案改进while的判断语句,因为while里只对if后那句做了判断,所以应该将if的条件合并入while,这样在stack不空的时候可以少一次if判断。

    public int[] dailyTemperaturesv4b(int[] T) {
        int[] result = new int[T.length];
        Stack<Integer> stack = new Stack<>();
        for(int i=0;i<T.length;i++) {
            while(!stack.empty()&&T[i]>T[stack.peek()]) {
                int index = stack.pop();
                result[index]=i-index;
            }
            stack.push(i);
        }
        return result;
    }

然而还是有人更快,方法5,用int[]手动代替stack:

class Solution {
    public int[] dailyTemperatures(int[] T) {
        int[] result = new int[T.length];
        int[] stack = new int[T.length];
        int top = -1;
        for(int i=0;i<T.length;i++) {
            while(top>-1&&T[i]>T[stack[top]]) {
                int index = stack[top--];
                result[index]=i-index;
            }
            stack[++top]=i;
        }
        return result;
    }
}

牛逼牛逼,鼓掌鼓掌。

看来以后用stack或arraylist需要优化时,可以考虑一下数组手动替代法。

还有一种做法,方法6:

    public int[] dailyTemperatures(int[] T) {
        int[] result = new int[T.length];
        int[] next = new int[101];    //next[i] 用来存放下一个温度i的在T中的index
        Arrays.fill(next, Integer.MAX_VALUE);
        for(int i=T.length-1;i>=0;i--) {    //为了更新next数组,要倒序遍历
            int warmer_index = Integer.MAX_VALUE;    //warmer_index指T[i]的最近的更暖和一天的index的暂存
            for(int t=T[i]+1;t<=100;t++) {
                if(next[t]<warmer_index) warmer_index=next[t];
            }
            if(warmer_index<Integer.MAX_VALUE) result[i] = warmer_index-i;
            next[T[i]]=i;
        }
        return result;
    }   

是基本方法的另外一个思路,速度仅次于方法5

 

posted @ 2019-03-22 00:09  大胖子球花  阅读(326)  评论(0)    收藏  举报