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;
    }
}
相关推荐
徐凤年_3 小时前
rog_map参数理解
算法
春日见3 小时前
算法与数据结构----哈希表
数据结构·人工智能·算法·机器学习·自动驾驶·哈希算法·散列表
叩码以求索4 小时前
统计按位或能得到最大值的子集数目(一)
数据结构·算法
tachibana24 小时前
hot100 数组中的第K个最大元素(215)
java·数据结构·算法·leetcode
txzrxz4 小时前
单调队列讲解
数据结构·c++·算法·单调队列
不会就选b5 小时前
算法日常・每日刷题--<快排>4
算法
Keven_115 小时前
算法札记:树状数组的用途
数据结构·算法
用户677437175815 小时前
C++函数参数传递方式详解:string、string&、const string、const string&该怎么选?
算法
cpp_25016 小时前
P1540 [NOIP 2010 提高组] 机器翻译
数据结构·c++·算法·队列·noip·洛谷题解
晚笙coding6 小时前
LeetCode 98:验证二叉搜索树 —— 从局部判断到全局范围约束的递归思想
算法·leetcode·职场和发展