• LeetCode-Self Crossing


    You are given an array x of n positive numbers. You start at point (0,0) and moves x[0] metres to the north, then x[1] metres to the west, x[2] metres to the south, x[3] metres to the east and so on. In other words, after each move your direction changes counter-clockwise.

    Write a one-pass algorithm with O(1) extra space to determine, if your path crosses itself, or not.

    Example 1:

    Given x = [2, 1, 1, 2],
    ┌───┐
    │   │
    └───┼──>
        │
    
    Return true (self crossing)
    

    Example 2:

    Given x = [1, 2, 3, 4],
    ┌──────┐
    │      │
    │
    │
    └────────────>
    
    Return false (not self crossing)
    

    Example 3:

    Given x = [1, 1, 1, 1],
    ┌───┐
    │   │
    └───┼>
    
    Return true (self crossing)
    
    Analysis:
      There are two possible modes: 1. Area is expanding, and 2. Area is shrinking. We need to identify the current mode.

      For shrinking mode, let current index be i, then if x[i] < x[i-2], x[i] is safe.
      For expanding mode, it is more complicated. For index i, there are 3 possible situations:
        1. x[i] > x[i-2]: still expanding mode, safe
        2. x[i] < x[i-2] - x[i-4]: switch to shrink mode, but safe
        3. x[i] >= x[i-2] - x[i-4]: switch to shrink mode, but possibly not safe, we need further determine, see the code.

    Solution:
     1 public class Solution {
     2     public boolean isSelfCrossingExpand(int[] x, int start){
     3         for (int i=start;i<x.length;i++){
     4             if (x[i] > x[i-2]){
     5                 continue;
     6             } else {
     7                 // becomes shrink mode
     8                 int bar = (i>=4) ? x[i-4] : 0;
     9                 if (x[i] <= x[i-2] && x[i] >= (x[i-2] - bar)){
    10                     if ( i+1 == x.length){
    11                         return false;
    12                     }
    13                     if (x[i+1] >= (x[i-1] - x[i-3])){
    14                         return true;
    15                     }
    16                     return isSelfCrossingShrink(x,i+2);
    17                 } else {
    18                     return isSelfCrossingShrink(x,i+1);
    19                 }
    20             }        
    21         }
    22         return false;
    23     }
    24 
    25     public boolean isSelfCrossingShrink(int[] x, int start){
    26         for (int i=start; i<x.length;i++){
    27             if (x[i] >= x[i-2])
    28                 return true;
    29         }
    30         return false;
    31     }
    32     public boolean isSelfCrossing(int[] x) {
    33         if (x.length<=3) return false;
    34 
    35         if (x[2] <= x[0]) return isSelfCrossingShrink(x,3);        
    36         return isSelfCrossingExpand(x,3);
    37         
    38     }
    39 }

            
  • 相关阅读:
    JavaScript 基础第七天(DOM的开始)
    JavaScript 基础第六天
    JavaScript 基础第五天
    JavaScript 基础第四天
    JavaScript 基础第三天
    JavaScript 基础第二天
    观《幸福终点站》有感
    山东移动2014校园招聘笔试
    Genymotion虚拟Android不能联网的一种解决方法
    关于Thinkpad E420双显卡驱动安装和切换的问题
  • 原文地址:https://www.cnblogs.com/lishiblog/p/5666896.html
Copyright © 2020-2023  润新知