【Leetcode】975. Odd Even Jump

题目地址:

https://leetcode.com/problems/odd-even-jump/

给定一个长 n n n数组 A A A,从某个点出发,其第 1 , 3 , 5 , . . . 1,3,5,... 1,3,5,...次跳跃称为“奇数跳”,第 2 , 4 , 6 , . . . 2,4,6,... 2,4,6,...次跳跃称为“偶数跳”。奇数跳可以跳到当前位置之后的某个位置,跳到的位置的数值一定不能小于当前数值,并且是所有满足条件的数值最小的位置;偶数跳则相反,也是跳到当前位置之后的某个位置,但跳到的位置的数值一定不能大于当前数值,并且是所有满足条件的数值最大的位置。问从哪些位置出发可以跳到 A [ n − 1 ] A[n-1] A[n1],返回可以到达目标点的出发位置的个数。

单调栈做法参考https://blog.csdn.net/qq_46105170/article/details/119529472。下面介绍简单一些的TreeMap的做法。设 f [ i ] [ 0 ] f[i][0] f[i][0] f [ i ] [ 1 ] f[i][1] f[i][1]表示当前位于 i i i并且正在执行偶数跳和奇数跳是否能跳到终点,那么如果是奇数跳的话,需要在后面找到最小的大于等于当前数的数的下标,如果是偶数跳的话,需要在后面找到最大的小于等于当前数的数的下标,这两者可以用TreeMap来实现。设 g 0 [ i ] g_0[i] g0[i] g 1 [ i ] g_1[i] g1[i]分别表示从 i i i执行偶数跳和奇数跳所跳到的位置,那么有: f [ i ] [ 0 ] = f [ g 0 [ i ] ] [ 1 ] f [ i ] [ 1 ] = f [ g 1 [ i ] ] [ 0 ] f[i][0]=f[g_0[i]][1]\\f[i][1]=f[g_1[i]][0] f[i][0]=f[g0[i]][1]f[i][1]=f[g1[i]][0]初始化 f [ n − 1 ] [ 0 ] = f [ n − 1 ] [ 1 ] = 1 f[n-1][0]=f[n-1][1]=1 f[n1][0]=f[n1][1]=1,本身已经在终点了,所以赋值为true。其余只需要统计 f [ i ] [ 1 ] = 1 f[i][1]=1 f[i][1]=1的位置数量即可。代码如下:

import java.util.Map;
import java.util.TreeMap;

public class Solution {
    public int oddEvenJumps(int[] arr) {
        int n = arr.length;
        boolean[][] f = new boolean[n][2];
        f[n - 1][0] = f[n - 1][1] = true;
        
        int res = 1;
        TreeMap<Integer, Integer> map = new TreeMap<>();
        map.put(arr[n - 1], n - 1);
        for (int i = n - 2; i >= 0; i--) {
            int x = arr[i];
            Map.Entry<Integer, Integer> floor = map.floorEntry(x), ceil = map.ceilingEntry(x);
            if (floor != null) {
                f[i][0] = f[floor.getValue()][1];
            }
            if (ceil != null) {
                f[i][1] = f[ceil.getValue()][0];
            }
        
            map.put(arr[i], i);
            
            if (f[i][1]) {
                res++;
            }
        }
        
        return res;
    }
}

时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),空间 O ( n ) O(n) O(n)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值