【每日一题Day325】LC2596检查骑士巡视方案 | 小顶堆/排序+模拟

简介: 【每日一题Day325】LC2596检查骑士巡视方案 | 小顶堆/排序+模拟

检查骑士巡视方案【LC2596】

骑士在一张 n x n 的棋盘上巡视。在有效的巡视方案中,骑士会从棋盘的 左上角 出发,并且访问棋盘上的每个格子 恰好一次 。

给你一个 n x n 的整数矩阵 grid ,由范围 [0, n * n - 1] 内的不同整数组成,其中 grid[row][col] 表示单元格 (row, col) 是骑士访问的第 grid[row][col] 个单元格。骑士的行动是从下标 0 开始的。

如果 grid 表示了骑士的有效巡视方案,返回 true;否则返回 false。

注意,骑士行动时可以垂直移动两个格子且水平移动一个格子,或水平移动两个格子且垂直移动一个格子。下图展示了骑士从某个格子出发可能的八种行动路线。

image.png

思路:

将每个单元格位置和值组成的三元组放入小顶堆中,保证按顺序移动。

首先需要判断起点是否位于左上角,否则直接返回false【因为这个WA了】

然后判断能否移动至下一个位置,根据横纵坐标的差值判断,差值的可能性有八种,如果符合任意一种则移动至下一个位置,否则返回false

如果可以移动至最后一个节点,那么返回true

实现

class Solution {
    public boolean checkValidGrid(int[][] grid) {
        int n = grid.length;
        // 存储三元组
        PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[2] - o2[2]);
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                pq.add(new int[]{i, j, grid[i][j]});
            }
        }
        // 判断起点
        int[] pre = pq.poll();
        if (pre[0] != 0 || pre[1] != 0) return false;
        while (!pq.isEmpty()){
            int[] next = pq.poll();
            int[] move = {next[0] - pre[0], next[1] - pre[1]};
            // 判断能否移动至下一个位置
            if (!isCorrect(move)){
                return false;
            }
            pre = next;
        }
        return true;
    }
    public boolean isCorrect(int[] move){
        int[] d1 = {2, -2};
        int[] d2 = {1, -1};
        for (int i = 0; i < 2; i++){
            for (int j = 0; j < 2;j++){
                if (move[0] == d1[i] && move[1] == d2[j]){
                    return true;
                }
                if (move[0] == d2[i] && move[1] == d1[j]){
                    return true;
                }
            }
        }
        return false;
    }
}

复杂度

时间复杂度:O(n^2)

空间复杂度:O(n^2)

目录
相关文章
|
6月前
【每日一题Day168】LC2427公因子的数目 | 模拟
【每日一题Day168】LC2427公因子的数目 | 模拟
38 1
|
6月前
【每日一题Day361】LC2558从数量最多的堆取走礼物 | 大顶堆
【每日一题Day361】LC2558从数量最多的堆取走礼物 | 大顶堆
39 0
|
6月前
【每日一题Day258】LC2532过桥的时间 | 模拟 优先队列
【每日一题Day258】LC2532过桥的时间 | 模拟 优先队列
44 0
|
6月前
【每日一题Day179】LC1157子数组中占绝大多数的元素 | 线段树
【每日一题Day179】LC1157子数组中占绝大多数的元素 | 线段树
52 0
|
6月前
【每日一题Day118】LC1124表现良好的最长时间段 | 前缀和+单调栈/哈希表
【每日一题Day118】LC1124表现良好的最长时间段 | 前缀和+单调栈/哈希表
54 0
|
6月前
【每日一题Day287】LC24 两两交换链表中的节点 | 模拟 递归
【每日一题Day287】LC24 两两交换链表中的节点 | 模拟 递归
44 0
|
4月前
|
存储 算法 测试技术
力扣经典150题第五十四题:最小栈
力扣经典150题第五十四题:最小栈
38 0
|
6月前
|
vr&ar
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
72 1
|
6月前
|
存储
【每日一题Day276】LC2208将数组和减半的最少操作次数 | 贪心+大顶堆
【每日一题Day276】LC2208将数组和减半的最少操作次数 | 贪心+大顶堆
43 0
|
6月前
【每日一题Day269】LC1851包含每个查询的最小区间 | 排序+离线查询+小顶堆
【每日一题Day269】LC1851包含每个查询的最小区间 | 排序+离线查询+小顶堆
42 0