5 Apr 2018

739. daily temperatures

  The problem link is Daily Temperatures.

Given a list of daily temperatures, produce a list that, for each day in the input, tells you how many days you would have to wait until a warmer temperature. If there is no future day for which this is possible, put 0 instead.
For example, given the list temperatures = [73, 74, 75, 71, 69, 72, 76, 73], your output should be [1, 1, 4, 2, 1, 1, 0, 0].

  you can easily solve this problem in O^2.

public static int[] dailyTemperatures(int[] temperatures) {
	int[] ret = new int[temperatures.length];
	for (int i = 0; i < temperatures.length; ++i)
		for (int j = i + 1; j < temperatures.length; ++j) {
			if (temperatures[i] < temperatures[j]) {
				ret[i] = j - i;
				break;
			}
		}

	return ret;
}

  But O^2 algorithm is not enough. How to optimize this algorithm? Are there some connections between consecutive computes? When we want to compute ret[i+1],can I use ret[i]? We know ret[temperatures.length()-1] is 0, So I decided to compute backward. If ret[i] < ret [i+1] then ret[i] =1, But If ret[i] >=ret[i+1], how to find the first subsequent item which greater than ret[i]? iterate? So I use a array to record the index of item which is the first subsequent item greater than current.I can find the first subsequent item greater than ret[i] recursively through this array. The recursive search may be O^n at worst case, But generally faster.

public static int[] dailyTemperatures(int[] temperatures) {
	int[] ret = new int[temperatures.length], index = new int[temperatures.length];
	ret[temperatures.length - 1] = 0;
	index[temperatures.length - 1] = -1;

	for (int i = temperatures.length - 2; i >= 0; --i) {
		int tmp = i + 1, count = 0;
		while (tmp != -1 && temperatures[i] >= temperatures[tmp]) {
			count += ret[tmp];
			tmp = index[tmp];
		}
		if (tmp == -1) {
			index[i] = -1;
			ret[i] = 0;
		} else {
			ret[i] = count + 1;
			index[i] = tmp;
		}
	}
	return ret;
}

Tags: