日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

太平洋大西洋水流问题如何解决?一文了解图在前端中的应用

發(fā)布時間:2023/12/4 HTML 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 太平洋大西洋水流问题如何解决?一文了解图在前端中的应用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一文了解圖在前端中的應用

  • 🎧序言
  • 🎤一、圖是什么?
    • 1、定義
    • 2、舉例
  • 🎹二、圖的表示法
    • 1、鄰接矩陣表示法
    • 2、鄰接表表示法
  • 🎺三、圖的常用操作
    • 1、圖的深度優(yōu)先遍歷
      • (1)定義
      • (2)口訣
      • (3)代碼實現(xiàn)
    • 2、圖的廣度優(yōu)先遍歷
      • (1)定義
      • (2)口訣
      • (3)代碼實現(xiàn)
  • 🎻四、leetcode經(jīng)典題目解析
    • 1、leetcode417太平洋大西洋水流問題(中等)
    • 2、leetcode133克隆圖(中等)
    • 3、leetcode65有效數(shù)字(困難)
  • 🎸五、結束語
  • 🐣彩蛋時間Painted Eggshell
    • 往期推薦
    • 番外篇

🎧序言

在我們的日常生活中,圖無處不在。小到一張小小地圖,大到我們我們乘坐的航班,每一個都跟圖有著緊密的聯(lián)系。

而對于前端來說,圖的應用也是相對比較廣泛的。圖常用于克隆圖、太平洋大西洋水流問題、有效數(shù)字的判斷等等場景。

在下面的這篇文章中,將講解關于圖的一些基礎知識,以及圖在前端中的常見應用。

一起來學習吧~??

🎤一、圖是什么?

1、定義

  • 圖是由頂點的集合邊的集合組成的。
  • 圖是網(wǎng)絡結構的抽象模型,是一組由連接的節(jié)點
  • 圖可以表示任何二元關系,比如道路航班……。
  • JS 中沒有圖,但是可以用 Object 和 Array 構建圖。
  • 圖的表示法:領接矩陣、鄰接表、關聯(lián)矩陣……

2、舉例

地鐵線路中每一個站點可以看成是一個頂點,而連接著每個站點的線路可以看做是邊。

🎹二、圖的表示法

圖通常有兩種表示法:領接矩陣和鄰接表。下面一起來看這兩種表示法~

1、鄰接矩陣表示法

下面用一張圖來展示鄰接矩陣的表示法。詳情見下圖👇

2、鄰接表表示法

大家可以看到上面的鄰接矩陣,在矩陣中存在著大量的0,這將會占據(jù)程序中大量的內(nèi)存。因此,我們引入了鄰接表,來解決這個問題。詳情見下圖👇

🎺三、圖的常用操作

1、圖的深度優(yōu)先遍歷

(1)定義

  • 圖的深度優(yōu)先遍歷,即盡可能深的搜索圖的分支。

(2)口訣

  • 訪問根節(jié)點。
  • 對根節(jié)點沒訪問過的相鄰節(jié)點挨個進行深度優(yōu)先遍歷。

(3)代碼實現(xiàn)

接下來我們用 JS 來實現(xiàn)圖的深度優(yōu)先遍歷,這里我們采用鄰接表的形式來表示。具體代碼如下:

我們先來定義一個圖的結構:

const graph = {0:[1, 2],1:[2],2:[0, 3],3:[3] }

接下來來對這個結構進行深度優(yōu)先遍歷:

const visited = new Set();const dfs = (n) => { console.log(n);//將訪問過的節(jié)點加入集合中visited.add(n);//對當前節(jié)點所對應的數(shù)組挨個進行遍歷graph[n].forEach(c => {// 對沒有訪問過的在此訪問if(!visited.has(c)){//遞歸進行深度遍歷dfs(c);}}) } //以2為起始點進行深度優(yōu)先遍歷 dfs(2);

最后我們來看下打印結果:

/*打印結果: 2 0 1 3 */

2、圖的廣度優(yōu)先遍歷

(1)定義

  • 圖的廣度優(yōu)先遍歷,先訪問離根節(jié)點最近的節(jié)點。

(2)口訣

  • 新建一個隊列,把根節(jié)點入隊。
  • 把隊頭出隊并訪問。
  • 把隊頭每訪問過的相鄰節(jié)點入隊。
  • 重復第二、三步操作,直到隊列為空。

(3)代碼實現(xiàn)

接下來我們用 JS 來實現(xiàn)圖的廣度優(yōu)先遍歷,這里我們采用鄰接表的形式來表示。具體代碼如下:

同樣地我們先來定義一個圖的結構:

const graph = {0:[1, 2],1:[2],2:[0, 3],3:[3] }

接下來來對這個結構進行深度優(yōu)先遍歷:

//新建一個集合,存放訪問過的節(jié)點 const visited = new Set(); //初始節(jié)點放進集合中 visited.add(2); //將初始節(jié)點放入隊列q中 const q = [2];while(q.length){//刪除隊列q的第一個元素,并將其值返回const n = q.shift();//打印返回后的值console.log(n);//將該值所對應鄰接表的數(shù)組,挨個進行遍歷graph[n].forEach(c => {//判斷數(shù)組中的元素是否已經(jīng)訪問過if(!visited.has(c)){//如果沒有訪問過則加入訪問隊列和訪問集合q.push(c);visited.add(c);}}); }

最后我們來看下打印結果:

/*打印結果: 2 0 3 1 */

🎻四、leetcode經(jīng)典題目解析

接下來我們引用幾道經(jīng)典的 leetcode 算法,來鞏固的知識。

溫馨小提示: 題意的內(nèi)容范例是對官方題目的簡單概要,并不是特別全面,建議大家先點擊鏈接查看,使用體驗更為友好~

1、leetcode417太平洋大西洋水流問題(中等)

(1)題意

附上題目鏈接:leetcode417太平洋大西洋水流問題

給定一個 m x n 的非負整數(shù)矩陣來表示一片大陸上各個單元格的高度。“太平洋”處于大陸的左邊界和上邊界,而“大西洋”處于大陸的右邊界和下邊界。

規(guī)定水流只能按照上、下、左、右四個方向流動,且只能從高到低或者在同等高度上流動。

請找出那些水流既可以流動到“太平洋”,又能流動到“大西洋”的陸地單元的坐標。

提示:

  • 輸出坐標的順序不重要
  • m 和 n 都小于150

輸入輸出示例:

  • 給定下面的 5x5 矩陣:太平洋 ~ ~ ~ ~ ~ ~ 1 2 2 3 (5) *~ 3 2 3 (4) (4) *~ 2 4 (5) 3 1 *~ (6) (7) 1 4 5 *~ (5) 1 1 2 4 ** * * * * 大西洋返回:[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (上圖中帶括號的單元).

(2)解題思路

  • 把矩陣想象成圖。
  • 從海岸線逆流而上遍歷圖,所到之處就是可以留到某個大洋的坐標。

(3)解題步驟

  • 新建兩個矩陣,分別記錄能留到兩個大洋的坐標。
  • 從海岸線,多管旗下,同時深度優(yōu)先遍歷圖,過程中填充上述矩陣。
  • 遍歷兩個矩陣,找出能流到兩個大洋的坐標。

(4)代碼實現(xiàn)

/*** @param {number[][]} matrix* @return {number[][]}*/let pacificAtlantic = function(matrix) {// 如果傳入的不是一個矩陣,則返回一個空數(shù)組if(!matrix && !matrix[0]){return [];}// m表示矩陣的行數(shù),n表示矩陣的列數(shù)const m = matrix.length;// matrix[0]表示矩陣的第一行const n = matrix[0].length;// 定義flow1記錄留到太平洋的坐標,flow2記錄留到大西洋的坐標// from方法構建長度為m的數(shù)組,第二個參數(shù)填充指定數(shù)組的值填充為什么樣const flow1 = Array.from({length: m}, () => new Array(n).fill(false));const flow2 = Array.from({length: m}, () => new Array(n).fill(false));// console.log(flow1);// console.log(flow2);// 進行深度優(yōu)先遍歷// r即row,表示行;c即column,表示列// flow為二維數(shù)組const dfs = (r, c, flow) => {flow[r][c] = true;[[r -1, c],[r + 1, c],[r, c - 1], [r, c + 1]].forEach(([nr,nc]) => {if(// 保證在矩陣中nr >= 0 && nr < m &&nc >= 0 && nc < n &&// 防止死循環(huán)!flow[nr][nc] &&// 保證逆流而上,即保證下一個節(jié)點的值大于上一個節(jié)點的值matrix[nr][nc] >= matrix[r][c]){dfs(nr, nc, flow);}});};// 沿著海岸線逆流而上for(let r = 0; r < m; r++){//第一列的流到太平洋,即flow1dfs(r, 0, flow1);//最后一列的留到大西洋,即flow2dfs(r, n - 1, flow2);}for(let c = 0; c < n; c++){//第一行的流到太平洋,即flow1dfs(0, c, flow1);//最后一行的留到大西洋,即flow2dfs(m - 1, c, flow2);}//收集能留到兩個大洋里的坐標const res = [];for(let r = 0; r < m; r++){for(let c = 0; c < n; c++){//當flow1和flow2都為true時,則說明既能留到太平洋,也能流到大西洋if(flow1[r][c] && flow2[r][c]){res.push([r, c]);}}}return res; }; console.log(pacificAtlantic([[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]]))/*打印結果: [[ 0, 4 ], [ 1, 3 ],[ 1, 4 ], [ 2, 2 ],[ 3, 0 ], [ 3, 1 ],[ 4, 0 ] ] */

2、leetcode133克隆圖(中等)

(1)題意

附上題目鏈接:leetcode133克隆圖

給你無向 連通 圖中一個節(jié)點的引用,請你返回該圖的 深拷貝(克隆)。

圖中的每個節(jié)點都包含它的值 val(int) 和其鄰居的列表(list[Node])。

class Node {public int val;public List<Node> neighbors; }

輸入輸出示例:

  • 輸入: adjList = [[2,4],[1,3],[2,4],[1,3]]
  • 輸出: [[2,4],[1,3],[2,4],[1,3]]
  • 解釋:
    • 圖中有 4 個節(jié)點。
    • 節(jié)點 1 的值是 1,它有兩個鄰居:節(jié)點 2 和 4 。
    • 節(jié)點 2 的值是 2,它有兩個鄰居:節(jié)點 1 和 3 。
    • 節(jié)點 3 的值是 3,它有兩個鄰居:節(jié)點 2 和 4 。
    • 節(jié)點 4 的值是 4,它有兩個鄰居:節(jié)點 1 和 3 。

(2)解題思路

  • 拷貝所有節(jié)點。
  • 拷貝所有的邊。

(3)解題步驟

  • 深度或廣度優(yōu)先遍歷所有節(jié)點。
  • 拷貝所有的結點,存儲起來。
  • 將拷貝的結點,按照原圖的連接方法進行連接。

(4)代碼實現(xiàn)

我們用兩種方式來實現(xiàn)克隆圖:深度優(yōu)先遍歷和廣度優(yōu)先遍歷。具體代碼如下:

深度優(yōu)先遍歷:

/*** // Definition for a Node.* function Node(val, neighbors) {* this.val = val === undefined ? 0 : val;* //鄰居節(jié)點是一個數(shù)組* this.neighbors = neighbors === undefined ? [] : neighbors;* };*//*** @param {Node} node* @return {Node}*/ // 深度優(yōu)先遍歷 let cloneGraph1 = function(node) {//如果當前節(jié)點為空,則直接返回if(!node){return;}//定義一個字典,存放訪問過的節(jié)點const visited = new Map();//深度優(yōu)先遍歷const dfs = (n) => {// 拷貝一份當前初始節(jié)點的值const nCopy = new Node(n.val);//將拷貝后的節(jié)點放到訪問字典當中visited.set(n, nCopy);//對初始節(jié)點的鄰居節(jié)點挨個進行遍歷(n.neighbors || []).forEach(ne => {//判斷訪問隊列是否有過鄰居節(jié)點if(!visited.has(ne)){/* 如果訪問隊列沒有過該鄰居節(jié)點,則將鄰居節(jié)點繼續(xù)進行深度遍歷*/dfs(ne);}// 將訪問過的鄰居節(jié)點的值拷貝到nCopy上nCopy.neighbors.push(visited.get(ne));});};dfs(node);return visited.get(node); };

廣度優(yōu)先遍歷:

/*** // Definition for a Node.* function Node(val, neighbors) {* this.val = val === undefined ? 0 : val;* //鄰居節(jié)點是一個數(shù)組* this.neighbors = neighbors === undefined ? [] : neighbors;* };*//*** @param {Node} node* @return {Node}*/ let cloneGraph2 = function(node) {//如果當前節(jié)點為空,則直接返回if(!node){return;}//定義一個字典,存放訪問過的節(jié)點const visited = new Map();//visited存放節(jié)點以及節(jié)點的值visited.set(node, new Node(node.val));// 初始化一個隊列const q = [node];// 當隊列內(nèi)有節(jié)點信息時while(q.length){// 刪除隊列中的第一個元素并返回值const n = q.shift();//將節(jié)點的鄰居挨個進行遍歷(n.neighbors || []).forEach(ne => {// 判斷訪問隊列是否有過鄰居節(jié)點if(!visited.has(ne)){// 將節(jié)點的鄰居加入到隊列中q.push(ne);// 將節(jié)點的鄰居及鄰居的值放入visited中visited.set(ne, new Node(ne.val));}/*如果訪問隊列已經(jīng)有過該節(jié)點,則將此節(jié)點放入訪問隊列的鄰居節(jié)點*/visited.get(n).neighbors.push(visited.get(ne));});}//返回訪問隊列的節(jié)點信息return visited.get(node); };

3、leetcode65有效數(shù)字(困難)

(1)題意

附上題目鏈接:leetcode65有效數(shù)字

有效數(shù)字(按順序)可以分成以下幾個部分:

  • 一個 小數(shù) 或者 整數(shù)
  • (可選)一個 'e' 或 'E' ,后面跟著一個 整數(shù)

小數(shù)(按順序)可以分成以下幾個部分:

  • (可選)一個符號字符('+' 或 '-')

  • 下述格式之一:

    • 至少一位數(shù)字,后面跟著一個點 '.'
    • 至少一位數(shù)字,后面跟著一個點 '.' ,后面再跟著至少一位數(shù)字
    • 一個點 '.' ,后面跟著至少一位數(shù)字

整數(shù)(按順序)可以分成以下幾個部分:

  • (可選)一個符號字符('+' 或 '-')
  • 至少一位數(shù)字

輸入輸出示例:

  • 輸入: s = “0”
  • 輸出: true

(2)解題思路-圖例

(3)解題步驟

  • 構建一個表示狀態(tài)的圖。
  • 遍歷字符串,并沿著圖走,如果到了某個節(jié)點無路可走就返回false。
  • 遍歷結束,如走到3/5/6,就返回true,否則返回false。

(4)代碼實現(xiàn)

let isNumber = function(s){const graph = {0:{'blank': 0, 'sign': 1, '.': 2, 'digit': 6 },1:{'digit': 6, '.': 2 },2:{'digit': 3 },3:{'digit': 3, 'e': 4 },4:{'digit': 5, 'sign': 7 },5:{'digit': 5 },6:{'digit': 6, '.': 3, 'e': 4 },7:{'digit': 5 }}let state = 0;for(c of s.trim()){if(c >= '0' && c <= '9'){c = 'digit';}else if(c === ' '){c = 'blank';}else if(c === '+' || c === '-'){c = 'sign';}state = graph[state][c];if(state === undefined){return false;}}if(state === 3 || state === 5 || state === 6){return true;}return false; }

🎸五、結束語

通過上文的學習,我們了解到了圖的兩種表示法:鄰接矩陣表示法鄰接表表示法。同時,還學習了圖的兩種常用操作:圖的深度優(yōu)先遍歷圖的廣度優(yōu)先遍歷。最后,我們引用了幾道 leetcode 算法題,來解決了圖的一些常用場景。

個人認為,圖相對于其他數(shù)據(jù)結構來說,學習難度更大一點,但又是一個不得不學的基本知識,所以還是得多加練習。

除此之外呢,對于以上算法題,學有余力之余,可以考慮多調(diào)試一步步跟著調(diào)試走,慢慢的就理解的更透徹了。

關于圖在前端中的應用講到這里就結束啦!希望對大家有幫助~

如有疑問或文章有誤歡迎評論區(qū)留言或公眾號后臺加我微信提問~

🐣彩蛋時間Painted Eggshell

往期推薦

棧👉棧在前端中的應用,順便再了解下深拷貝和淺拷貝!

隊列👉詳解隊列在前端的應用,深剖JS中的事件循環(huán)Eventloop,再了解微任務和宏任務

鏈表👉詳解鏈表在前端的應用,順便再弄懂原型和原型鏈!

字典和集合👉ES6的Set和Map你都知道嗎?一文了解集合和字典在前端中的應用

樹👉一文了解樹在前端中的應用,掌握數(shù)據(jù)結構中樹的生命線

動態(tài)規(guī)則和分而治之算法👉一文了解分而治之和動態(tài)規(guī)則算法在前端中的應用

貪心算法和回溯算法👉一文了解貪心算法和回溯算法在前端中的應用

番外篇

  • 關注公眾號星期一研究室,第一時間關注學習干貨,更多精選專欄待你解鎖~
  • 如果這篇文章對你有用,記得留個腳印jio再走哦~
  • 以上就是本文的全部內(nèi)容!我們下期見!👋👋👋

總結

以上是生活随笔為你收集整理的太平洋大西洋水流问题如何解决?一文了解图在前端中的应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。