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;
    }
}
相关推荐
点云SLAM13 分钟前
二叉树算法详解和C++代码示例
数据结构·c++·算法·红黑树·二叉树算法
今天背单词了吗9807 小时前
算法学习笔记:19.牛顿迭代法——从原理到实战,涵盖 LeetCode 与考研 408 例题
笔记·学习·算法·牛顿迭代法
jdlxx_dongfangxing8 小时前
进制转换算法详解及应用
算法
why技术9 小时前
也是出息了,业务代码里面也用上算法了。
java·后端·算法
2501_9228955810 小时前
字符函数和字符串函数(下)- 暴力匹配算法
算法
IT信息技术学习圈10 小时前
算法核心知识复习:排序算法对比 + 递归与递推深度解析(根据GESP四级题目总结)
算法·排序算法
愚润求学11 小时前
【动态规划】01背包问题
c++·算法·leetcode·动态规划
会唱歌的小黄李11 小时前
【算法】贪心算法入门
算法·贪心算法
轻语呢喃12 小时前
每日LeetCode : 两数相加--链表操作与进位的经典处理
javascript·算法
钢铁男儿12 小时前
C# 接口(接口可以继承接口)
java·算法·c#