【Leetcode】335. Self Crossing

题目地址:

https://leetcode.com/problems/self-crossing/

给定一个长 n n n的正整数数组 d d d,在平面直角坐标系里从 ( 0 , 0 ) (0,0) (0,0)出发,然后按照上、左、下、右的循环顺序,每次走 d [ i ] d[i] d[i]的距离。问按照 d d d里的距离这么走,中间是否会走到之前走到过的位置。

因为按照数组 d d d的距离走下去,如果一直不相交,那么一定是一圈一圈绕的更大,或者一圈一圈绕的更小。所以本质上,如果有相交,一定是最近的几步有相交。

设当前走的距离是 d [ i ] d[i] d[i],先假定 i i i 1 1 1开始计数。首先前 3 3 3步是不会自交的,第 4 4 4步自交当且仅当 d [ 3 ] ≤ d [ 1 ] ∧ d [ 4 ] ≥ d [ 2 ] d[3]\le d[1]\land d[4]\ge d[2] d[3]d[1]d[4]d[2],这是第 1 1 1种情况;如果第 4 4 4步没有自交但第 5 5 5步发生自交了,并且 d [ 3 ] > d [ 1 ] d[3]>d[1] d[3]>d[1],那么此时如果 d [ 5 ] d[5] d[5]发生自交了,则 d [ 2 , 3 , 4 , 5 ] d[2,3,4,5] d[2,3,4,5] d [ 1 , 2 , 3 , 4 ] d[1,2,3,4] d[1,2,3,4]的情况本质上是一样的,略过;如果不是这种情况,那一定有 d [ 4 ] = d [ 2 ] , d [ 5 ] + d [ 1 ] ≥ d [ 3 ] d[4]=d[2],d[5]+d[1]\ge d[3] d[4]=d[2],d[5]+d[1]d[3],这是第 2 2 2种情况;如果 d [ 4 ] < d [ 2 ] d[4]<d[2] d[4]<d[2],接下来自交也是第 1 1 1种情况,并且这样画是一圈一圈绕的更小,一旦发生自交一定是情况 1 1 1,就不用讨论了;如果第 5 5 5步没有自交,但是第 6 6 6步发生自交了,那么就是 d [ 3 ] ≥ d [ 5 ] , d [ 5 ] + d [ 1 ] ≥ d [ 3 ] , d [ 4 ] > d [ 2 ] , d [ 2 ] + d [ 6 ] ≥ d [ 4 ] d[3]\ge d[5],d[5]+d[1]\ge d[3],d[4]>d[2],d[2]+d[6]\ge d[4] d[3]d[5],d[5]+d[1]d[3],d[4]>d[2],d[2]+d[6]d[4]。后面再走的话就不可能与 d [ 1 ] d[1] d[1]相交了,那么如果再相交的话一定也是前面的几种情况。只需要枚举这几种情况会不会发生即可。代码如下:

public class Solution {
    public boolean isSelfCrossing(int[] d) {
        if (d.length <= 3) {
            return false;
        }
        
        for (int i = 3; i < d.length; i++) {
            if (d[i - 1] <= d[i - 3] && d[i - 2] <= d[i]) {
                return true;
            }
            if (i >= 4 && d[i - 3] == d[i - 1] && d[i] + d[i - 4] >= d[i - 2]) {
                return true;
            }
            if (i >= 5 && d[i - 3] >= d[i - 1] && d[i - 1] + d[i - 5] >= d[i - 3] && d[i - 2] > d[i - 4] && d[i - 4] + d[i] >= d[i - 2]) {
                return true;
            }
        }
        
        return false;
    }
}

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值