lintcode 1832 · 最小步数【BFS 中等】

题目

https://www.lintcode.com/problem/1832

java 复制代码
有一个1∗n的棋盘,分别标号为0,1,2..n−1,棋盘的每个格子都有一种颜色。
现在,在0号位置有一枚棋子,请求出最少移动几步能到达最后一格。
棋子有3种移动的方法,且棋子不能移出到棋盘外:

棋子从位置 i 移动到位置 i+1。
棋子从位置 i 移动到位置 i−1。
如果位置 i 和位置 j 的颜色相同,那么棋子可以直接从位置 i 移动到位置 j。

棋盘的大小为 1∗n,2≤n≤10 ^5 。
第 i 格子的颜色编号 colors i ,满足 1≤colors i  ≤n。

样例
样例 1

输入:
colors = [1, 2, 3, 3, 2, 5]
输出:
3
解释:
在样例中,棋子最少用 3 步走到最后的位置:
1. 从位置 0 走到位置 1。
2. 由于位置 1 和位置 4 的颜色相同,从位置 1 走到位置 4。
3. 从位置 4 走到位置 5。

前置知识

复制代码
宽度优先遍历BFS

代码

java 复制代码
public class Solution {
    /**
     * @param colors: the colors of grids
     * @return: return the minimum step from position 0 to position n - 1
     */
    public int minimumStep(List<Integer> colors) {
        //colors = [1, 2, 3, 3, 2, 5]
        // BFS
        Map<Integer,List<Integer>> sameColor = new HashMap<>(); //k:颜色  v:位置列表
        int n= colors.size();
        for (int i = 0; i <n; i++) {
            int c = colors.get(i);
            if(!sameColor.containsKey(c))
                sameColor.put(c,new ArrayList<>());

            sameColor.get(c).add(i);
        }


        boolean[] visited = new boolean[n];
        Queue<Integer> q = new LinkedList<>(); //q 存放位置下标
        q.add(0); //从0开始
        visited[0]= true;
        int steps =0;
        while (!q.isEmpty()){
            int size = q.size();
            boolean arriveEnd= false;
            for (int i = 0; i <size ; i++) {
                int cur= q.poll();
                if(cur == n-1) {
                    arriveEnd = true;
                    break;
                }
                List<Integer> nexts = getNexts(cur,colors,sameColor,visited);
                for (Integer next : nexts) {
                    visited[next] =true;
                    q.add(next);
                }
                // cur对应的颜色都走过了,将其在哈希表里删除
                sameColor.remove(colors.get(cur));   //本题要通过,这里是关键
            }

            if(arriveEnd) break;

            steps++;  //走了一步了
        }
        return steps;
    }

    //到cur位置时再获取该位置可以跳的位置
    public static List<Integer> getNexts(int cur,List<Integer> colors,Map<Integer,List<Integer>> sameColor,boolean[] visited){
        List<Integer> nexts = new ArrayList<>();
        int n= colors.size();
        // 向右走
        if (cur<= n -2 && !visited[cur + 1]) {
            nexts.add(cur + 1);
        }
        // 如果走到n - 1的位置了,直接返回
        if (nexts.contains(n - 1)) {
            return nexts;
        }
        // 向左走
        if (cur >= 1 && !visited[cur - 1]) {
            nexts.add(cur - 1);
        }


        //向相同的颜色走
        int c = colors.get(cur);
        if(sameColor.containsKey(c)){
            for (Integer next : sameColor.get(c)) {
                if(next ==n-1){
                    return Arrays.asList(n-1);
                }

                if(!visited[next])
                    nexts.add(next);
            }
        }
        return nexts;
    }
}
相关推荐
开开心心就好几秒前
文件关联被破坏怎么修?免费工具一键修复
java·服务器·开发语言·pdf·ocr·启发式算法·宽度优先
垆边人似月.4 分钟前
华为题:矩阵中的最长递增路径
算法·深度优先
小诗懂技术7 分钟前
linux驱动中断,相关中断的方式与适用场景
linux·arm开发·驱动开发·算法
不会就选b11 分钟前
算法日常・每日刷题--<动态规划>25
算法
Keep_Trying_Go20 分钟前
分割算法FastSAM论文详解
深度学习·算法·计算机视觉
星夜离尘5620 分钟前
MATLAB 5 点滑动平均:filter 与 conv 的输出对齐,以及 2 样本延时的含义
开发语言·算法·matlab·滤波·fir
Dovis(誓平步青云)25 分钟前
总用电下降了,为什么家庭能源看板仍然提示异常
java·开发语言·数据库·人工智能·算法·电脑·能源
开开心心就好29 分钟前
A3的PDF怎么切成A4?拖一下分割线就行
服务器·开发语言·python·算法·pdf·ocr·tornado
闻缺陷则喜何志丹1 小时前
详细设计说明书的内容要求
算法·测试·存储
和裕1 小时前
定制纸箱刀卡、平卡、隔档分别是什么?结构与适用场景区别全解析
大数据·运维·网络·人工智能·算法