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


浙公网安备 33010602011771号