最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java超詳細精講數(shù)據(jù)結(jié)構(gòu)之bfs與雙端隊列

 更新時間:2022年07月21日 15:20:59   作者:撩得Android一次心動  
廣搜BFS的基本思想是: 首先訪問初始點v并將其標志為已經(jīng)訪問。接著通過鄰接關(guān)系將鄰接點入隊。然后每訪問過一個頂點則出隊。按照順序,訪問每一個頂點的所有未被訪問過的頂點直到所有的頂點均被訪問過。廣度優(yōu)先遍歷類似與層次遍歷

一.bfs

bfs(廣度優(yōu)先搜索),類似二叉樹的層序遍歷,利用隊列完成。一般用于求最短路。

圖的最短路問題:

給定一個無向圖,每條邊的長度都是1。求1號點到x號點的最短距離。 頂點數(shù)n 邊數(shù)為m

q次詢問 輸入x 輸出1到x的最短距離。 若1號點到x不連通,則輸出-1

二.雙端隊列

雙端隊列的應(yīng)用(區(qū)間翻轉(zhuǎn)):

對于長度為n的數(shù)組,給定一個長度為m的區(qū)間,區(qū)間初始位置為a[1]到a[m]。

3種操作:

  • 區(qū)間右移(最右端不會超過a[n])
  • 區(qū)間左移(最左端不會超過a[n])
  • 區(qū)間內(nèi)所有數(shù)翻轉(zhuǎn)。

q次操作后請你還原數(shù)組。

三.算法題

1.kotori和迷宮

難度??

知識點:bfs

首先找到k字母,然后從k字母位置開始bfs。bfs過程中即可得到k到每個e的最短路程。(要注意走過的e不可繼續(xù)往下走)

題目描述:

kotori在一個n*m迷宮里,迷宮的最外層被巖漿淹沒,無法涉足,迷宮內(nèi)有k個出口。kotori只能上下左右四個方向移動。她想知道有多少出口是她能到達的,最近的出口離她有多遠?

輸入描述:

第一行為兩個整數(shù)n和m,代表迷宮的行和列數(shù) (1≤n,m≤30)

后面緊跟著n行長度為m的字符串來描述迷宮。'k'代表kotori開始的位置,'.'代表道路,'*'代表墻壁,'e'代表出口。保證輸入合法。

輸出描述:

若有出口可以抵達,則輸出2個整數(shù),第一個代表kotori可選擇的出口的數(shù)量,第二個代表kotori到最近的出口的步數(shù)。(注意,kotori到達出口一定會離開迷宮)

若沒有出口可以抵達,則輸出-1。

示例1

輸入

6 8
e.*.*e.*
.**.*.*e
..*k**..
***.*.e*
.**.*.**
*......e

輸出

2 7

說明

可供選擇坐標為[4,7]和[6,8],到kotori的距離分別是8和7步。

import java.util.*;
import java.io.*;
public class Main{
  public static void main(String[] args) throws IOException{
    BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
    String[] s1 = bf.readLine().split(" ");
    int n = Integer.parseInt(s1[0]);
    int m = Integer.parseInt(s1[1]);
    //建立地圖、標記圖
    char[][] maze = new char[n][m];
    boolean[][] visited = new boolean[n][m];
    //紀錄步數(shù)
    int[][] dis = new int[n][m];
    //紀錄初始的坐標
    int ki = 0, kj = 0;
    for(int i = 0; i < n; i++){
      String s = bf.readLine();
      for(int j = 0; j < m; j++){
         dis[i][j] = Integer.MAX_VALUE;
         char c = s.charAt(j);
         maze[i][j] = c;
         if(c == 'k'){
          ki = i;
          kj = j;
        }
      }
    }
    int count = 0, min = Integer.MAX_VALUE;
    Queue<Integer> queue = new ArrayDeque<>();
    //二維數(shù)組的性質(zhì),保存了坐標,并且節(jié)省了空間
    queue.add(ki * m + kj);
    visited[ki][kj] = true;
    dis[ki][kj]= 0;
    while(!queue.isEmpty()){
      int temp = queue.poll();
      int tempi = temp / m, tempj = temp % m;
      //支持八個方向的移動或者不移動(但是因為Math.abs(i - j) == 1限定了絕對值為1,所以變成了四個方向)
      for(int i = -1; i <= 1; i++){
        for(int j = -1; j <= 1; j++){
          if(Math.abs(i - j) == 1 && tempi + i >= 0 && tempi + i < n && tempj + j >= 0 && tempj + j < m && !visited[tempi + i][tempj + j]){
            if(maze[tempi + i][tempj + j] == '.'){
              visited[tempi + i][tempj + j] = true;
              dis[tempi + i][tempj + j] = dis[tempi][tempj] + 1;
              queue.add((tempi + i) * m + (tempj + j));
            }
            if(maze[tempi + i][tempj + j] == 'e'){
              visited[tempi + i][tempj + j] = true;
              dis[tempi + i][tempj + j] = dis[tempi][tempj] + 1;
              min = Math.min(min, dis[tempi][tempj] + 1);
              count++;
            }
          }
        }
      } 
    }
    if(count == 0) System.out.print(-1);
    else System.out.print(count + " " + min);
  }
}

思考:隊列是怎么實現(xiàn)bfs的?

1.起始點入隊-->2.將起始點四個方向的可達點入隊-->3.起始點出隊。以此循序依次訪問隊列中的元素。

2.小紅找紅點

難度???

知識點:bfs,多源最短路

多源最短路的求法:在bfs開始之前將所有點都扔進隊列,然后開始bfs即可。

題目描述:

小紅拿到了一張無向圖,有 n個頂點和m條邊。每條邊的長度為 1 。

小紅給一些頂點染成了紅色。她想知道,對于每個頂點,到附近最近的紅色點的距離為多少?

輸入描述:

第一行輸出兩個正整數(shù) n 和 m ,用空格隔開。分別代表頂點數(shù)和邊數(shù)。

第二行輸入一個長度為 n 的字符串,代表每個頂點的染色情況。第i 個字符為 'R' 代表被染成紅色,為 'W' 代表未被染色。

接下來的m 行,每行兩個正整數(shù) x 和y ,代表x 和y 有一條無向邊相連。

不保證圖是整體連通的。不保證沒有重邊和自環(huán)。

1<=n,m<=10^5

輸出描述:

輸出一行 n 個整數(shù),代表從1 到 n 每個頂點到最近的紅色頂點的距離。若對于某點而言無論如何都走不到紅色頂點,則輸出 -1 。

示例1:

輸入

5 5
RWWRW
1 2
3 3
1 2
2 5
1 4

輸出

0 1 -1 0 2

說明

樣例的圖如上所示。

import java.util.*;
import java.io.*;
public class Main{
    static ArrayList<Integer>[] g;
    static String[] strings;
    static int[] visited;
    static int[] dis;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] firstLine = br.readLine().split(" ");
        int n = Integer.parseInt(firstLine[0]);
        int m = Integer.parseInt(firstLine[1]);
        g = new ArrayList[n+1];
        visited = new int[n+1];
        dis= new int[n+1];
        for (int i=1;i<n+1;i++) {
            g[i] = new ArrayList<Integer>();
        }
        //一個字符一個字符的讀取
        strings = br.readLine().split("");
        for (int i=0;i<m;i++) {
            //描繪雙向圖
            String[] temp = br.readLine().split(" ");
            int x = Integer.parseInt(temp[0]);
            int y = Integer.parseInt(temp[1]);
            g[x].add(y);
            g[y].add(x);
        }
        //g[x]代表當(dāng)前點 g[x].get(i)代表所連的線
        Queue<Integer> queue = new ArrayDeque<>();
        for(int i=1;i<=n;i++){
            if(strings[i-1].equals("R")){
                queue.add(i);
                visited[i]=1;
            }
        }
        while(!queue.isEmpty()){
            int temp=queue.remove();
            for(int i=0;i<g[temp].size();i++){
                if(visited[g[temp].get(i)]==0){
                    visited[g[temp].get(i)]=1;
                    dis[g[temp].get(i)]=dis[temp]+1;
                    queue.add(g[temp].get(i));
                }
            }
        }
        for(int i=1;i<=n;i++){
            if(visited[i]==0)System.out.print("-1 ");
            else System.out.print(dis[i]+" ");
        }
    }
}

對照上一章的案例:小紅點點點結(jié)合理解。 分別使用的dfs和bfs。

本題思想:先將紅色的所有點都入隊列,然后bfs。

這是一種逆向思維:不是所謂的從編號開始,并且所有走過的都不能在走了。

3.小紅玩數(shù)組

難度????

知識點:雙端隊列

用一個雙端隊列來模擬過程,用一個變量來標記雙端隊列是否翻轉(zhuǎn)過。

示例1:

輸入

6 4
1 5 4 6 2 8
5
21323

輸出

4 6 2 1 5 8

import java.io.*;
import java.util.*;
public class Main{
    static Deque<Integer> workQueue;
    public static void main(String[] args)throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw=new PrintWriter(System.out);
        String[] firstLine=br.readLine().split(" ");
        int total=Integer.parseInt(firstLine[0]);
        int size=Integer.parseInt(firstLine[1]);
        int[] arr=new int[total];
        String[] secondLine=br.readLine().split(" ");
        for(int i=0;i<total;i++){
            arr[i]=Integer.parseInt(secondLine[i]);
        }
        int L=0;
        int R=size-1;
        workQueue=new LinkedList<>();
        for(int i=0;i<size;i++){
            workQueue.offerLast(arr[i]);
        }
        int times=Integer.parseInt(br.readLine());
        String tries=br.readLine();
        int is=0;//0代表沒有翻轉(zhuǎn)!
        for(int i=0;i<times;i++){
            if(tries.charAt(i)=='1'){
                if(R==arr.length-1)
                    continue;
                R++;
                if(is==0){
                    workQueue.offerLast(arr[R]);
                    int tmp=workQueue.pollFirst();
                    arr[L]=tmp;
                }else{
                    workQueue.offerFirst(arr[R]);
                    int tmp=workQueue.pollLast();
                    arr[L]=tmp;
                }
                L++;
            }else if(tries.charAt(i)=='2'){
                if(L==0)
                    continue;
                L--;
                if(is==0){
                    workQueue.offerFirst(arr[L]);
                    arr[R]=workQueue.pollLast();
                }else{
                    workQueue.offerLast(arr[L]);
                    arr[R]=workQueue.pollFirst();
                }
                R--;
            }else{
                is=1-is;
            }
        }
        for(int i=0;i<L;i++){
            pw.print(arr[i]+" ");
        }
        if(is==0){
            while(!workQueue.isEmpty()) {
                pw.print(workQueue.pollFirst() + " ");
            }
        }else{
            while(!workQueue.isEmpty()) {
                pw.print(workQueue.pollLast() + " ");
            }
        }
        for(int i=R+1;i<arr.length;i++){
            pw.print(arr[i]+" ");
        }
        pw.flush();
    }
}

到此這篇關(guān)于Java超詳細精講數(shù)據(jù)結(jié)構(gòu)之bfs與雙端隊列的文章就介紹到這了,更多相關(guān)Java bfs與雙端隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 面試題和答案 -(上)

    Java 面試題和答案 -(上)

    本文主要介紹Java 面試題和答案,這里整理了Java面試中出現(xiàn)的各種題型,和相應(yīng)知識點,有需要的小伙伴可以好好參考下,幫助大家面試成功
    2016-09-09
  • RocketMQ消息丟失的場景以及解決方案

    RocketMQ消息丟失的場景以及解決方案

    Apache RocketMQ是企業(yè)級的消息中間件,以其高性能和高可靠性而廣泛應(yīng)用,但是,消息丟失的問題在實踐中仍然存在,本文將探討此問題并提供解決方案,需要的朋友可以參考下
    2023-11-11
  • 詳解Java如何判斷一個對象是否為空

    詳解Java如何判斷一個對象是否為空

    我們在剛開始學(xué)習(xí)Java的時候,遇到過最多的異??隙ㄊ浅裘阎目罩羔槷惓#∟ullPointerException),可以說它陪伴了我們整個初學(xué)階段,那么如何優(yōu)雅的判斷一個對象是否為空并且減少空指針異常呢,
    2024-01-01
  • Java 中的 BufferedReader 介紹_動力節(jié)點Java學(xué)院整理

    Java 中的 BufferedReader 介紹_動力節(jié)點Java學(xué)院整理

    BufferedReader 是緩沖字符輸入流。它繼承于Reader。接下來通過本文給大家介紹BufferedReader的相關(guān)知識,需要的朋友參考下吧
    2017-05-05
  • java一個接口多個實現(xiàn)類的調(diào)用方式

    java一個接口多個實現(xiàn)類的調(diào)用方式

    這篇文章主要給大家介紹了關(guān)于java一個接口多個實現(xiàn)類的調(diào)用方式的相關(guān)資料,經(jīng)測試確認,當(dāng)一個接口有多個實現(xiàn)時,調(diào)用時只會執(zhí)行一個,有時候需要多個實現(xiàn)調(diào)用,需要的朋友可以參考下
    2023-09-09
  • IDEA最新版2020.1的maven工程本地依賴倉庫無法使用問題(已解決)

    IDEA最新版2020.1的maven工程本地依賴倉庫無法使用問題(已解決)

    這篇文章主要介紹了IDEA最新版2020.1的maven工程本地依賴倉庫無法使用問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • java Map轉(zhuǎn)Object與Object轉(zhuǎn)Map實現(xiàn)代碼

    java Map轉(zhuǎn)Object與Object轉(zhuǎn)Map實現(xiàn)代碼

    這篇文章主要介紹了 java Map轉(zhuǎn)Object與Object轉(zhuǎn)Map實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • 基于Nacos實現(xiàn)Spring Cloud Gateway實現(xiàn)動態(tài)路由的方法

    基于Nacos實現(xiàn)Spring Cloud Gateway實現(xiàn)動態(tài)路由的方法

    這篇文章主要介紹了基于Nacos實現(xiàn)Spring Cloud Gateway實現(xiàn)動態(tài)路由的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • jpa 使用@Column來定義字段類型

    jpa 使用@Column來定義字段類型

    這篇文章主要介紹了jpa使用@Column來定義字段類型,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java中notify和notifyAll的區(qū)別及何時使用

    Java中notify和notifyAll的區(qū)別及何時使用

    本文主要介紹了Java中notify和notifyAll的區(qū)別及何時使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評論

青铜峡市| 吉安市| 屏南县| 古浪县| 崇明县| 陈巴尔虎旗| 清新县| 钟山县| 诏安县| 泽州县| 扶绥县| 广灵县| 施秉县| 论坛| 小金县| 清丰县| 武宁县| 神池县| 湘潭县| 澜沧| 通河县| 贡嘎县| 农安县| 禹州市| 冕宁县| 高雄县| 梅河口市| 涟源市| 若尔盖县| 密云县| 托克逊县| 舒城县| 昆山市| 上饶市| 南郑县| 东方市| 梁平县| 信宜市| 永康市| 同心县| 江永县|