Leetcode: 1496. 判断路径是否相交

题目

给你一个字符串 path,其中 path[i] 的值可以是 'N'、'S'、'E' 或者 'W',分别表示向北、向南、向东、向西移动一个单位。

机器人从二维平面上的原点 (0, 0) 处开始出发,按 path 所指示的路径行走。

如果路径在任何位置上出现相交的情况,也就是走到之前已经走过的位置,请返回 True ;否则,返回 False 。


示例 1:

输入:path = "NES"
输出:false 
解释:该路径没有在任何位置相交。


示例 2:

输入:path = "NESWW"
输出:true
解释:该路径经过原点两次。


提示:

1 <= path.length <= 10^4
path 仅由 {'N', 'S', 'E', 'W} 中的字符组成

分析

对于这类查找是否出现重复的问题,最常用的方法是利用 Hash 表查找。值得注意的是,HashSet 判断重复的方式。由于 HashSet 的底层是 HashMap,将插入的元素作为 HashMap 的键值,所以 HashSet 判断重复的方式和 HashMap 是一样的。

首先,调用 Object 类 中的 hashCode() 方法,然后再调用 equals() 方法。

由于本题目中需要插入的是坐标,我们可以用三种方式解决:

  1. 定义 Point 类,重写 hashCode() 和 equals() 方法。
  2. 将坐标转化为字符串,String 类中已经重写过 hashCode() 和 equals() 了。
  3. 利用 Pair 类,Pair 类中也已经重写过 hashCode() 和 equals() 了。

代码

1. 定义 Point 类

class Solution {
    public class Point {
        int x;
        int y;
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o.getClass() != this.getClass()) return false;
            Point obj = (Point) o;
            return this.x == obj.x && this.y == obj.y;
        }
        public int hashCode() {
            return Objects.hash(this.x, this.y);
        }
    }
    public boolean isPathCrossing(String path) { 
        Set<Point> set = new HashSet<>();
        set.add(new Point(0, 0));
        char[] array = path.toCharArray();
        int x = 0, y = 0;
        for (char c : array) {
            Point newPoint;
            switch(c){
                case 'N':
                    newPoint = new Point(x, ++y);
                    break;
                case 'S':
                    newPoint = new Point(x, --y);
                    break;
                case 'E':
                    newPoint = new Point(++x, y);
                    break;
                case 'W':
                    newPoint = new Point(--x, y);
                    break;
                default:
                    newPoint = new Point(0, 0);
            }
            if (set.contains(newPoint)) return true;
            set.add(newPoint);
        }
        return false;
    }
}

用时:1ms

2. 利用 String 类

class Solution {
    public boolean isPathCrossing(String path) {
        int x = 0, y = 0;
        Set<String> set = new HashSet<>();
        set.add(x + "-" + y);
        char[] array = path.toCharArray();
        for (char c : array) {
            switch(c) {
                case 'N':
                    if (set.contains(x + "-" + (++y))) return true;
                    set.add(x + "-" + y);
                    break;
                case 'S':
                    if (set.contains(x + "-" + (--y))) return true;
                    set.add(x + "-" + y);
                    break;
                case 'E':
                    if (set.contains((++x) + "-" + y)) return true;
                    set.add(x + "-" + y);
                    break;
                case 'W':
                    if (set.contains((--x) + "-" + y)) return true;
                    set.add(x + "-" + y);
                    break;
            }
        }
        return false;
    }
}

用时: 8ms

3. 利用 Pair 类

class Solution {
    public boolean isPathCrossing(String path) {
        int x = 0, y = 0;
        Set<Pair<Integer, Integer>> set = new HashSet<>();
        set.add(new Pair<>(x, y));
        char[] array = path.toCharArray();
        Pair<Integer, Integer> p;
        for (char c : array) {
            switch(c) {
                case 'N':
                    p = new Pair<>(x, ++y);
                    if (set.contains(p)) return true;
                    set.add(p);
                    break;
                case 'S':
                    p = new Pair<>(x, --y);
                    if (set.contains(p)) return true;
                    set.add(p);
                    break;
                case 'E':
                    p = new Pair<>(++x, y);
                    if (set.contains(p)) return true;
                    set.add(p);
                    break;
                case 'W':
                    p = new Pair<>(--x, y);
                    if (set.contains(p)) return true;
                    set.add(p);
                    break;
            }
        }
        return false;
    }
}

用时:1ms

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值