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;
    }
}
相关推荐
菜鸟求带飞_1 小时前
算法打卡:第十一章 图论part01
java·数据结构·算法
浅念同学1 小时前
算法.图论-建图/拓扑排序及其拓展
算法·图论
是小Y啦1 小时前
leetcode 106.从中序与后续遍历序列构造二叉树
数据结构·算法·leetcode
liuyang-neu1 小时前
力扣 42.接雨水
java·算法·leetcode
y_dd1 小时前
【machine learning-12-多元线性回归】
算法·机器学习·线性回归
m0_631270401 小时前
标准c语言(一)
c语言·开发语言·算法
万河归海4281 小时前
C语言——二分法搜索数组中特定元素并返回下标
c语言·开发语言·数据结构·经验分享·笔记·算法·visualstudio
小周的C语言学习笔记1 小时前
鹏哥C语言36-37---循环/分支语句练习(折半查找算法)
c语言·算法·visual studio
y_dd1 小时前
【machine learning-七-线性回归之成本函数】
算法·回归·线性回归
小魏冬琅2 小时前
K-means 算法的介绍与应用
算法·机器学习·kmeans