LeetCode 335. Self Crossing(貪吃蛇)


原題網址:https://leetcode.com/problems/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)

方法:模擬移動的過程來判斷,是否交叉跟最近6個點所連成的線段有關。

public class Solution {
    public boolean isSelfCrossing(int[] x) {
        if (x == null || x.length < 4) return false;
        int[] rows = new int[6];
        int[] cols = new int[6];
        for(int i=0; i<x.length; i++) {
            int nrow = rows[5], ncol = cols[5];
            switch (i%4) {
                case 0: nrow -= x[i]; break;
                case 1: ncol -= x[i]; break;
                case 2: nrow += x[i]; break;
                case 3: ncol += x[i]; break;
            }
            
            if (i >= 5) {
                switch (i%4) {
                    case 0: 
                        if (cols[0] <= ncol && ncol <= cols[1] && rows[5] >= rows[1] && rows[1] >= nrow) return true;
                        else break;
                    case 1: 
                        if (rows[1] <= nrow && nrow <= rows[0] && cols[5] >= cols[1] && cols[1] >= ncol) return true; 
                        else break;
                    case 2: 
                        if (cols[1] <= ncol && ncol <= cols[0] && rows[5] <= rows[1] && rows[1] <= nrow) return true; 
                        else break;
                    case 3: 
                        if (rows[0] <= nrow && nrow <= rows[1] && cols[5] <= cols[1] && cols[1] <= ncol) return true;
                        else break;
                }
            }
            if (i >= 3) {
                switch (i%4) {
                    case 0: 
                        if (cols[3] <= ncol && ncol <= cols[2] && rows[5] <= rows[3] && rows[3] <= nrow) return true;
                        else break;
                    case 1: 
                        if (rows[2] <= nrow && nrow <= rows[3] && cols[5] >= cols[3] && cols[3] >= ncol) return true; 
                        else break;
                    case 2: 
                        if (cols[2] <= ncol && ncol <= cols[3] && rows[5] <= rows[2] && rows[2] <= nrow) return true; 
                        else break;
                    case 3: 
                        if (rows[3] <= nrow && nrow <= rows[2] && cols[5] <= cols[2] && cols[2] <= ncol) return true;
                        else break;
                }
            }
            if (i==4 && ncol == 0 && rows[5] > 0 && nrow <= 0) return true;
            rows[0] = rows[1];
            rows[1] = rows[2];
            rows[2] = rows[3];
            rows[3] = rows[4];
            rows[4] = rows[5];
            rows[5] = nrow;
            cols[0] = cols[1];
            cols[1] = cols[2];
            cols[2] = cols[3];
            cols[3] = cols[4];
            cols[4] = cols[5];
            cols[5] = ncol;
        }
        return false;
    }
}


另一種實現:

public class Solution {
    public boolean isSelfCrossing(int[] x) {
        int[] row = new int[7];
        int[] col = new int[7];
        for(int i=0; i<x.length; i++) {
            for(int j=0; j<6; j++) {
                row[j]=row[j+1];
                col[j]=col[j+1];
            }
            switch (i % 4) {
                case 0:
                    row[6] = row[5] - x[i];
                    col[6] = col[5];
                    if (i >= 8 && col[0] <= col[5] && col[5] <= col[1] && row[6] <= row[0] && row[0] <= row[5]) return true;
                    if (i >= 4 && col[3] <= col[5] && col[5] <= col[2] && row[6] <= row[2] && row[2] <= row[5]) return true;
                    if (i == 4 && col[6] == 0 && row[6] <= 0) return true;
                    break;
                case 1:
                    row[6] = row[5];
                    col[6] = col[5] - x[i];
                    if (i >= 5 && col[6] <= col[0] && col[0] <= col[5] && row[1] <= row[5] && row[5] <= row[0]) return true;
                    if (i >= 5 && col[6] <= col[2] && col[2] <= col[5] && row[2] <= row[5] && row[5] <= row[3]) return true;
                    break;
                case 2:
                    row[6] = row[5] + x[i];
                    col[6] = col[5];
                    if (i >= 6 && col[1] <= col[5] && col[5] <= col[0] && row[5] <= row[0] && row[0] <= row[6]) return true;
                    if (i >= 6 && col[2] <= col[5] && col[5] <= col[3] && row[5] <= row[2] && row[2] <= row[6]) return true;
                    break;
                case 3:
                    row[6] = row[5];
                    col[6] = col[5] + x[i];
                    if (i >= 7 && col[5] <= col[0] && col[0] <= col[6] && row[0] <= row[5] && row[5] <= row[1]) return true;
                    if (i >= 3 && col[5] <= col[2] && col[2] <= col[6] && row[3] <= row[5] && row[5] <= row[2]) return true;
                    break;
            }
        }
        return false;
    }
}


另一種實現:


public class Solution {
    public boolean isSelfCrossing(int[] x) {
        int[] px = new int[6];
        int[] py = new int[6];
        int ny = 0;
        int nx = 0;
        for(int i = 0; i < x.length; i++) {
            switch (i % 4) {
                case 0:
                    ny -= x[i];
                    break;
                case 1:
                    nx -= x[i];
                    break;
                case 2:
                    ny += x[i];
                    break;
                case 3:
                    nx += x[i];
                    break;
            }
            if (i == 3) {
                if (px[3] <= px[0] && px[0] <= nx && py[1] <= ny && ny <= py[0]) return true;
            } else if (i == 4) {
                if (px[2] <= nx && nx <= px[1] && ny <= py[2] && py[2] <= py[4]) return true;
                if (nx == px[1] && ny <= py[0] && py[0] <= py[4]) return true;
            } else if (i > 4) {
                switch (i % 4) {
                    case 0:
                        if (px[0] <= nx && nx <= px[1] && ny <= py[1] && py[1] <= py[5]) return true;
                        if (px[3] <= nx && nx <= px[2] && ny <= py[3] && py[3] <= py[5]) return true;
                        break;
                    case 1:
                        if (nx <= px[1] && px[1] <= px[5] && py[1] <= ny && ny <= py[0]) return true;
                        if (nx <= px[3] && px[3] <= px[5] && py[2] <= ny && ny <= py[3]) return true;
                        break;
                    case 2:
                        if (px[1] <= nx && nx <= px[0] && py[5] <= py[1] && py[1] <= ny) return true;
                        if (px[2] <= nx && nx <= px[3] && py[5] <= py[3] && py[3] <= ny) return true;
                        break;
                    case 3:
                        if (px[5] <= px[1] && px[1] <= nx && py[0] <= ny && ny <= py[1]) return true;
                        if (px[5] <= px[3] && px[3] <= nx && py[3] <= ny && ny <= py[2]) return true;
                        break;
                }
            }
            if (i < 5) {
                px[i + 1] = nx;
                py[i + 1] = ny;
            } else {
                for(int j = 0; j < 5; j++) {
                    px[j] = px[j + 1];
                    py[j] = py[j + 1];
                }
                px[5] = nx;
                py[5] = ny;
            }
        }
        return false;
    }
}

有更巧妙的方法,參考:https://leetcode.com/discuss/88054/java-oms-with-explanation


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com