LeetCode刷题记153
975. 奇偶跳
class Solution {
public int oddEvenJumps(int[] A) {
if (A.length == 0) return 0;
// 记录每个数值出现在哪些下标中
List<Integer>[] ind = new ArrayList[100005]; // 记录下标
for (int i = 0; i < A.length; i ++) {
if (ind[A[i]] == null) {
ind[A[i]] = new ArrayList<Integer>();
}
ind[A[i]].add(i);
}
// 记录出现过的数字的下一个比他大的数字
int[] nt_max = new int[100005]; // 记录下一个大的数字
int[] nt_min = new int[100005]; // 记录下一个小的数字
Arrays.fill(nt_max, -1);
Arrays.fill(nt_min, -1);
int pre = -1;
for (int i = 0; i < 100001; i ++) {
if (ind[i] != null) {
if (pre != -1) {
nt_max[pre] = i;
nt_min[i] = pre;
}
pre = i;
}
}
// 记录从一个位置跳到下一个位置的下标
int[] nt_odd = new int[A.length]; // 记录奇数跳到下一个的位置
int[] nt_even = new int[A.length]; // 记录偶数跳到下一个的位置
Arrays.fill(nt_odd, -1);
Arrays.fill(nt_even, -1);
for (int i = 0; i < A.length; i ++) {
ind[A[i]].remove(0); // 删除自己的下标
if (ind[A[i]].size() > 0) { // 和自己一样的还有
nt_even[i] = nt_odd[i] = ind[A[i]].get(0);
} else {
while (nt_max[A[i]] != -1 && ind[nt_max[A[i]]].size() == 0) {
nt_max[A[i]] = nt_max[nt_max[A[i]]]; // 下一个大的没有下标了,跳到下下个
}
if (nt_max[A[i]] != -1 && ind[nt_max[A[i]]].size() >= 0 ) {
nt_odd[i] = ind[nt_max[A[i]]].get(0); // 奇数跳到下一个的位置
}
while (nt_min[A[i]] != -1 && ind[nt_min[A[i]]].size() == 0) {
nt_min[A[i]] = nt_min[nt_min[A[i]]]; // 下一个小的没有下标了,跳到下下个
}
if (nt_min[A[i]] != -1 && ind[nt_min[A[i]]].size() >= 0 ) {
nt_even[i] = ind[nt_min[A[i]]].get(0); // 偶数跳到下一个的位置
}
}
}
// 记录从某一点能否跳到终点
boolean[] odd = new boolean[A.length]; // 记录从i开始奇数跳能否到达终点
boolean[] even = new boolean[A.length]; // 记录从i开始偶数跳能否到达终点
odd[A.length - 1] = even[A.length - 1] = true;
int ans = 1; // 最后一个点一定是的
for (int i = A.length - 2; i >= 0; i --) {
// 下一个奇数跳跳过去的点,再进行一次偶数跳可以跳到终点
// 那么从这个点开始进行奇数跳就可以到达终点
if (nt_odd[i] != -1 && even[nt_odd[i]]) {
odd[i] = true;
ans ++; // 因为一开始是奇数跳,如果可以跳到最后,那么这个点就可以是一个答案
}
// 下一个偶数跳跳过去的点,再进行一次奇数跳可以跳到终点
// 那么从这个点开始进行偶数跳就可以到达终点
if (nt_even[i] != - 1 && odd[nt_even[i]]) {
even[i] = true; // 偶数跳开始可以跳到终点,但是不能算入答案
}
}
return ans;
}
}
题解都在代码注释里了,就是这个题目是栈的标签,但是我给做成了一个模拟题的感觉。
下面是官方的题解,没有我的快,哈哈哈哈哈,我上面的时间击败了100%,这个只有41.77%
class Solution {
public int oddEvenJumps(int[] A) {
int N = A.length;
if (N <= 1) return N;
boolean[] odd = new boolean[N];
boolean[] even = new boolean[N];
odd[N-1] = even[N-1] = true;
TreeMap<Integer, Integer> vals = new TreeMap();
vals.put(A[N-1], N-1);
for (int i = N-2; i >= 0; --i) {
int v = A[i];
if (vals.containsKey(v)) {
odd[i] = even[vals.get(v)];
even[i] = odd[vals.get(v)];
} else {
Integer lower = vals.lowerKey(v);
Integer higher = vals.higherKey(v);
if (lower != null)
even[i] = odd[vals.get(lower)];
if (higher != null) {
odd[i] = even[vals.get(higher)];
}
}
vals.put(v, i);
}
int ans = 0;
for (boolean b: odd)
if (b) ans++;
return ans;
}
}
作者:LeetCode
链接:https://leetcode-cn.com/problems/odd-even-jump/solution/qi-ou-tiao-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
但是感觉这个TreeMap很实用啊,TreeMap的用法