在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何用DFS算法來秒殺島嶼系列問題

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:labuladong ? 作者:labuladong ? 2021-11-16 17:13 ? 次閱讀

島嶼問題是經(jīng)典的面試高頻題,雖然基本的島嶼問題并不難,但是島嶼問題有一些有意思的擴展,比如求子島嶼數(shù)量,求形狀不同的島嶼數(shù)量等等,本文就來把這些問題一網(wǎng)打盡。

島嶼系列問題的核心考點就是用 DFS/BFS 算法遍歷二維數(shù)組

本文主要來講解如何用 DFS 算法來秒殺島嶼系列問題,不過用 BFS 算法的核心思路是完全一樣的,無非就是把 DFS 改寫成 BFS 而已。

那么如何在二維矩陣中使用 DFS 搜索呢?如果你把二維矩陣中的每一個位置看做一個節(jié)點,這個節(jié)點的上下左右四個位置就是相鄰節(jié)點,那么整個矩陣就可以抽象成一幅網(wǎng)狀的「圖」結(jié)構(gòu)。

根據(jù)學習數(shù)據(jù)結(jié)構(gòu)和算法的框架思維,完全可以根據(jù)二叉樹的遍歷框架改寫出二維矩陣的 DFS 代碼框架:

//二叉樹遍歷框架
voidtraverse(TreeNoderoot){
traverse(root.left);
traverse(root.right);
}

//二維矩陣遍歷框架
voiddfs(int[][]grid,inti,intj,boolean[]visited){
intm=grid.length,n=grid[0].length;
if(i0||j0||i>=m||j>=n){
//超出索引邊界
return;
}
if(visited[i][j]){
//已遍歷過(i,j)
return;
}
//前序:進入節(jié)點(i, j)
visited[i][j]=true;
dfs(grid,i-1,j);//上
dfs(grid,i+1,j);//下
dfs(grid,i,j-1);//左
dfs(grid,i,j+1);//右
//后序:離開節(jié)點(i, j)
// visited[i][j]=true;
}

因為二維矩陣本質(zhì)上是一幅「圖」,所以遍歷的過程中需要一個visited布爾數(shù)組防止走回頭路,如果你能理解上面這段代碼,那么搞定所有島嶼問題都很簡單。

這里額外說一個處理二維數(shù)組的常用小技巧,你有時會看到使用「方向數(shù)組」來處理上下左右的遍歷,和前文圖遍歷框架的代碼很類似:

//方向數(shù)組,分別代表上、下、左、右
int[][]dirs=newint[][]{{-1,0},{1,0},{0,-1},{0,1}};

voiddfs(int[][]grid,inti,intj,boolean[]visited){
intm=grid.length,n=grid[0].length;
if(i0||j0||i>=m||j>=n){
//超出索引邊界
return;
}
if(visited[i][j]){
//已遍歷過(i,j)
return;
}

//進入節(jié)點(i,j)
visited[i][j]=true;
//遞歸遍歷上下左右的節(jié)點
for(int[]d:dirs){
intnext_i=i+d[0];
intnext_j=j+d[1];
dfs(grid,next_i,next_j);
}
//離開節(jié)點(i,j)
// visited[i][j]=true;
}

這種寫法無非就是用 for 循環(huán)處理上下左右的遍歷罷了,你可以按照個人喜好選擇寫法。

島嶼數(shù)量

這是力扣第 200 題「島嶼數(shù)量」,最簡單也是最經(jīng)典的一道島嶼問題,題目會輸入一個二維數(shù)組grid,其中只包含0或者10代表海水,1代表陸地,且假設該矩陣四周都是被海水包圍著的。

我們說連成片的陸地形成島嶼,那么請你寫一個算法,計算這個矩陣grid中島嶼的個數(shù),函數(shù)簽名如下:

intnumIslands(char[][]grid);

比如說題目給你輸入下面這個grid有四片島嶼,算法應該返回 4:

思路很簡單,關(guān)鍵在于如何尋找并標記「島嶼」,這就要 DFS 算法發(fā)揮作用了,我們直接看解法代碼:

//主函數(shù),計算島嶼數(shù)量
intnumIslands(char[][]grid){
intres=0;
intm=grid.length,n=grid[0].length;
//遍歷grid
for(inti=0;ifor(intj=0;jif(grid[i][j]=='1'){
//每發(fā)現(xiàn)一個島嶼,島嶼數(shù)量加一
res++;
//然后使用DFS將島嶼淹了
dfs(grid,i,j);
}
}
}
returnres;
}

//從(i,j)開始,將與之相鄰的陸地都變成海水
voiddfs(char[][]grid,inti,intj){
intm=grid.length,n=grid[0].length;
if(i0||j0||i>=m||j>=n){
//超出索引邊界
return;
}
if(grid[i][j]=='0'){
//已經(jīng)是海水了
return;
}
//將(i,j)變成海水
grid[i][j]='0';
//淹沒上下左右的陸地
dfs(grid,i+1,j);
dfs(grid,i,j+1);
dfs(grid,i-1,j);
dfs(grid,i,j-1);
}

為什么每次遇到島嶼,都要用 DFS 算法把島嶼「淹了」呢?主要是為了省事,避免維護visited數(shù)組

因為dfs函數(shù)遍歷到值為0的位置會直接返回,所以只要把經(jīng)過的位置都設置為0,就可以起到不走回頭路的作用。

PS:這類 DFS 算法還有個別名叫做FloodFill 算法,現(xiàn)在有沒有覺得 FloodFill 這個名字還挺貼切的~

這個最最基本的島嶼問題就說到這,我們來看看后面的題目有什么花樣。

封閉島嶼的數(shù)量

上一題說二維矩陣四周可以認為也是被海水包圍的,所以靠邊的陸地也算作島嶼。

力扣第 1254 題「統(tǒng)計封閉島嶼的數(shù)目」和上一題有兩點不同:

1、用0表示陸地,用1表示海水。

2、讓你計算「封閉島嶼」的數(shù)目。所謂「封閉島嶼」就是上下左右全部被1包圍的0,也就是說靠邊的陸地不算作「封閉島嶼」

函數(shù)簽名如下:

intclosedIsland(int[][]grid)

比如題目給你輸入如下這個二維矩陣:

a6addc6e-46b3-11ec-b939-dac502259ad0.png

算法返回 2,只有圖中灰色部分的0是四周全都被海水包圍著的「封閉島嶼」。

那么如何判斷「封閉島嶼」呢?其實很簡單,把上一題中那些靠邊的島嶼排除掉,剩下的不就是「封閉島嶼」了嗎

有了這個思路,就可以直接看代碼了,注意這題規(guī)定0表示陸地,用1表示海水:

//主函數(shù):計算封閉島嶼的數(shù)量
intclosedIsland(int[][]grid){
intm=grid.length,n=grid[0].length;
for(intj=0;j//把靠上邊的島嶼淹掉
dfs(grid,0,j);
//把靠下邊的島嶼淹掉
dfs(grid,m-1,j);
}
for(inti=0;i//把靠左邊的島嶼淹掉
dfs(grid,i,0);
//把靠右邊的島嶼淹掉
dfs(grid,i,n-1);
}
//遍歷grid,剩下的島嶼都是封閉島嶼
intres=0;
for(inti=0;ifor(intj=0;jif(grid[i][j]==0){
res++;
dfs(grid,i,j);
}
}
}
returnres;
}

//從(i,j)開始,將與之相鄰的陸地都變成海水
voiddfs(int[][]grid,inti,intj){
intm=grid.length,n=grid[0].length;
if(i0||j0||i>=m||j>=n){
return;
}
if(grid[i][j]==1){
//已經(jīng)是海水了
return;
}
//將(i,j)變成海水
grid[i][j]=1;
//淹沒上下左右的陸地
dfs(grid,i+1,j);
dfs(grid,i,j+1);
dfs(grid,i-1,j);
dfs(grid,i,j-1);
}

只要提前把靠邊的陸地都淹掉,然后算出來的就是封閉島嶼了。

PS:處理這類島嶼問題除了 DFS/BFS 算法之外,Union Find 并查集算法也是一種可選的方法,前文Union Find 算法運用就用 Union Find 算法解決了一道類似的問題。

這道島嶼題目的解法稍微改改就可以解決力扣第 1020 題「飛地的數(shù)量」,這題不讓你求封閉島嶼的數(shù)量,而是求封閉島嶼的面積總和。

其實思路都是一樣的,先把靠邊的陸地淹掉,然后去數(shù)剩下的陸地數(shù)量就行了,注意第 1020 題中1代表陸地,0代表海水:

intnumEnclaves(int[][]grid){
intm=grid.length,n=grid[0].length;
//淹掉靠邊的陸地
for(inti=0;i0);
dfs(grid,i,n-1);
}
for(intj=0;j0,j);
dfs(grid,m-1,j);
}

//數(shù)一數(shù)剩下的陸地
intres=0;
for(inti=0;ifor(intj=0;jif(grid[i][j]==1){
res+=1;
}
}
}

returnres;
}

//和之前的實現(xiàn)類似
voiddfs(int[][]grid,inti,intj){
//...
}

篇幅所限,具體代碼我就不寫了,我們繼續(xù)看其他的島嶼問題。

島嶼的最大面積

這是力扣第 695 題「島嶼的最大面積」,0表示海水,1表示陸地,現(xiàn)在不讓你計算島嶼的個數(shù)了,而是讓你計算最大的那個島嶼的面積,函數(shù)簽名如下:

intmaxAreaOfIsland(int[][]grid)

比如題目給你輸入如下一個二維矩陣

其中面積最大的是橘紅色的島嶼,算法返回它的面積 6。

這題的大體思路和之前完全一樣,只不過dfs函數(shù)淹沒島嶼的同時,還應該想辦法記錄這個島嶼的面積

我們可以給dfs函數(shù)設置返回值,記錄每次淹沒的陸地的個數(shù),直接看解法吧:

intmaxAreaOfIsland(int[][]grid){
//記錄島嶼的最大面積
intres=0;
intm=grid.length,n=grid[0].length;
for(inti=0;ifor(intj=0;jif(grid[i][j]==1){
//淹沒島嶼,并更新最大島嶼面積
res=Math.max(res,dfs(grid,i,j));
}
}
}
returnres;
}

//淹沒與(i,j)相鄰的陸地,并返回淹沒的陸地面積
intdfs(int[][]grid,inti,intj){
intm=grid.length,n=grid[0].length;
if(i0||j0||i>=m||j>=n){
//超出索引邊界
return0;
}
if(grid[i][j]==0){
//已經(jīng)是海水了
return0;
}
//將(i,j)變成海水
grid[i][j]=0;

returndfs(grid,i+1,j)
+dfs(grid,i,j+1)
+dfs(grid,i-1,j)
+dfs(grid,i,j-1)+1;
}

解法和之前相比差不多,我也不多說了,接下來的兩道島嶼問題是比較有技巧性的,我們重點來看一下。

子島嶼數(shù)量

如果說前面的題目都是模板題,那么力扣第 1905 題「統(tǒng)計子島嶼」可能得動動腦子了:

這道題的關(guān)鍵在于,如何快速判斷子島嶼?肯定可以借助Union Find 并查集算法來判斷,不過本文重點在 DFS 算法,就不展開并查集算法了。

什么情況下grid2中的一個島嶼Bgrid1中的一個島嶼A的子島?

當島嶼B中所有陸地在島嶼A中也是陸地的時候,島嶼B是島嶼A的子島。

反過來說,如果島嶼B中存在一片陸地,在島嶼A的對應位置是海水,那么島嶼B就不是島嶼A的子島

那么,我們只要遍歷grid2中的所有島嶼,把那些不可能是子島的島嶼排除掉,剩下的就是子島。

依據(jù)這個思路,可以直接寫出下面的代碼:

intcountSubIslands(int[][]grid1,int[][]grid2){
intm=grid1.length,n=grid1[0].length;
for(inti=0;ifor(intj=0;jif(grid1[i][j]==0&&grid2[i][j]==1){
//這個島嶼肯定不是子島,淹掉
dfs(grid2,i,j);
}
}
}
//現(xiàn)在grid2中剩下的島嶼都是子島,計算島嶼數(shù)量
intres=0;
for(inti=0;ifor(intj=0;jif(grid2[i][j]==1){
res++;
dfs(grid2,i,j);
}
}
}
returnres;
}

//從(i,j)開始,將與之相鄰的陸地都變成海水
voiddfs(int[][]grid,inti,intj){
intm=grid.length,n=grid[0].length;
if(i0||j0||i>=m||j>=n){
return;
}
if(grid[i][j]==0){
return;
}

grid[i][j]=0;
dfs(grid,i+1,j);
dfs(grid,i,j+1);
dfs(grid,i-1,j);
dfs(grid,i,j-1);
}

這道題的思路和計算「封閉島嶼」數(shù)量的思路有些類似,只不過后者排除那些靠邊的島嶼,前者排除那些不可能是子島的島嶼。

不同的島嶼數(shù)量

這是本文的最后一道島嶼題目,作為壓軸題,當然是最有意思的。

力扣第 694 題「不同的島嶼數(shù)量」,題目還是輸入一個二維矩陣,0表示海水,1表示陸地,這次讓你計算不同的 (distinct)島嶼數(shù)量,函數(shù)簽名如下:

intnumDistinctIslands(int[][]grid)

比如題目輸入下面這個二維矩陣:

其中有四個島嶼,但是左下角和右上角的島嶼形狀相同,所以不同的島嶼共有三個,算法返回 3。

很顯然我們得想辦法把二維矩陣中的「島嶼」進行轉(zhuǎn)化,變成比如字符串這樣的類型,然后利用 HashSet 這樣的數(shù)據(jù)結(jié)構(gòu)去重,最終得到不同的島嶼的個數(shù)。

如果想把島嶼轉(zhuǎn)化成字符串,說白了就是序列化,序列化說白了遍歷嘛,前文二叉樹的序列化和反序列化講了二叉樹和字符串互轉(zhuǎn),這里也是類似的。

首先,對于形狀相同的島嶼,如果從同一起點出發(fā),dfs函數(shù)遍歷的順序肯定是一樣的

因為遍歷順序是寫死在你的遞歸函數(shù)里面的,不會動態(tài)改變:

voiddfs(int[][]grid,inti,intj){
//遞歸順序:
dfs(grid,i-1,j);//上
dfs(grid,i+1,j);//下
dfs(grid,i,j-1);//左
dfs(grid,i,j+1);//右
}

所以,遍歷順序從某種意義上說就可以用來描述島嶼的形狀,比如下圖這兩個島嶼:

假設它們的遍歷順序是:

下,右,上,撤銷上,撤銷右,撤銷下

如果我用分別用1, 2, 3, 4代表上下左右,用-1, -2, -3, -4代表上下左右的撤銷,那么可以這樣表示它們的遍歷順序:

2, 4, 1, -1, -4, -2

你看,這就相當于是島嶼序列化的結(jié)果,只要每次使用dfs遍歷島嶼的時候生成這串數(shù)字進行比較,就可以計算到底有多少個不同的島嶼了

要想生成這段數(shù)字,需要稍微改造dfs函數(shù),添加一些函數(shù)參數(shù)以便記錄遍歷順序:

voiddfs(int[][]grid,inti,intj,StringBuildersb,intdir){
intm=grid.length,n=grid[0].length;
if(i0||j0||i>=m||j>=n
||grid[i][j]==0){
return;
}
//前序遍歷位置:進入(i, j)
grid[i][j]=0;
sb.append(dir).append(',');

dfs(grid,i-1,j,sb,1);//上
dfs(grid,i+1,j,sb,2);//下
dfs(grid,i,j-1,sb,3);//左
dfs(grid,i,j+1,sb,4);//右

//后序遍歷位置:離開(i, j)
sb.append(-dir).append(',');
}

dir記錄方向,dfs函數(shù)遞歸結(jié)束后,sb記錄著整個遍歷順序,其實這就是前文回溯算法核心套路說到的回溯算法框架,你看到頭來這些算法都是相通的。

有了這個dfs函數(shù)就好辦了,我們可以直接寫出最后的解法代碼:

intnumDistinctIslands(int[][]grid){
intm=grid.length,n=grid[0].length;
//記錄所有島嶼的序列化結(jié)果
HashSetislands=newHashSet<>();
for(inti=0;ifor(intj=0;jif(grid[i][j]==1){
//淹掉這個島嶼,同時存儲島嶼的序列化結(jié)果
StringBuildersb=newStringBuilder();
//初始的方向可以隨便寫,不影響正確性
dfs(grid,i,j,sb,666);
islands.add(sb.toString());
}
}
}
//不相同的島嶼數(shù)量
returnislands.size();
}

這樣,這道題就解決了,至于為什么初始調(diào)用dfs函數(shù)時的dir參數(shù)可以隨意寫,這里涉及 DFS 和回溯算法的一個細微差別,前文圖算法基礎有寫,這里就不展開了。

以上就是全部島嶼系列問題的解題思路,也許前面的題目大部分人會做,但是最后兩題還是比較巧妙的,希望本文對你有幫助。
責任編輯:haq


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4612

    瀏覽量

    92901
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    417

    瀏覽量

    25947
  • DFS
    DFS
    +關(guān)注

    關(guān)注

    0

    文章

    26

    瀏覽量

    9165

原文標題:DFS 算法秒殺五道島嶼問題

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    11.11福利加碼!新增爆款商品與大額優(yōu)惠券秒殺,全場1折起,錯過等一年!

    尊敬的華秋商城客戶,感謝您的支持!雙11活動火熱進行中,為了讓您的購物更加盡興,我們特此福利加碼,11.11日當天新增爆款商品超低價秒殺、大額優(yōu)惠券秒殺,千萬不要錯過哦!完整活動亮相>>
    的頭像 發(fā)表于 11-08 01:02 ?145次閱讀
    11.11福利加碼!新增爆款商品與大額優(yōu)惠券<b class='flag-5'>秒殺</b>,全場1折起,錯過等一年!

    Pure path studio內(nèi)能否自己創(chuàng)建一個component,實現(xiàn)特定的算法,例如LMS算法

    TLV320AIC3254EVM-K評估模塊, Pure path studio軟件開發(fā)環(huán)境。 問題:1.Pure path studio 內(nèi)能否自己創(chuàng)建一個component,實現(xiàn)特定的算法
    發(fā)表于 11-01 08:25

    dp接口的最新技術(shù)發(fā)展

    深度優(yōu)先搜索(DFS)是一種基本的算法,用于遍歷或搜索樹或圖。它從一個頂點開始,盡可能深地搜索樹的分支。當搜索到最深節(jié)點時,然后回溯。DFS可以用于解決許多問題,如尋找路徑、檢測循環(huán)、拓撲排序等
    的頭像 發(fā)表于 10-30 13:52 ?170次閱讀

    何用Jacinto內(nèi)部的GPtimer輸出PWM信號控制屏幕背光

    電子發(fā)燒友網(wǎng)站提供《如何用Jacinto內(nèi)部的GPtimer輸出PWM信號控制屏幕背光.pdf》資料免費下載
    發(fā)表于 09-29 10:25 ?0次下載
    如<b class='flag-5'>何用</b>Jacinto內(nèi)部的GPtimer輸出PWM信號控制屏幕背光

    何用PMBus解碼UCD90xxx故障日志

    電子發(fā)燒友網(wǎng)站提供《如何用PMBus解碼UCD90xxx故障日志.pdf》資料免費下載
    發(fā)表于 09-25 10:04 ?0次下載
    如<b class='flag-5'>何用</b>PMBus解碼UCD90xxx故障日志

    何用 S7-200 實現(xiàn) Modbus 通信?

    電子發(fā)燒友網(wǎng)站提供《如何用 S7-200 實現(xiàn) Modbus 通信?.pdf》資料免費下載
    發(fā)表于 09-14 10:22 ?1次下載

    怎樣修改LVGL的lv_port_fs文件,讓它使用rt-thread的DFS文件系統(tǒng)中的API函數(shù)讀取SD卡中的圖片?

    我想問一下,怎樣修改LVGL的lv_port_fs文件,可以讓它使用rt-thread的DFS文件系統(tǒng)中的API函數(shù)(這些API函數(shù)在rt-thread的dfs_posix.c中)讀取SD卡中的圖片?
    發(fā)表于 07-11 06:53

    神經(jīng)網(wǎng)絡如何用無監(jiān)督算法訓練

    標記數(shù)據(jù)的處理尤為有效,能夠充分利用互聯(lián)網(wǎng)上的海量數(shù)據(jù)資源。以下將詳細探討神經(jīng)網(wǎng)絡如何用無監(jiān)督算法進行訓練,包括常見的無監(jiān)督學習算法、訓練過程、應用及挑戰(zhàn)。
    的頭像 發(fā)表于 07-09 18:06 ?801次閱讀

    算法系列:彩色轉(zhuǎn)灰度

    、整數(shù)算法 而實際應用時,為了避免低速的浮點運算,所以需要整數(shù)算法。 注意到系數(shù)都是3位精度的沒有,我們可以將它們縮放1000倍實現(xiàn)整數(shù)運算算法:Gray = (R*299
    發(fā)表于 05-22 19:02

    RTThread4.1.1在spiflash上掛dfs文件系統(tǒng)報互斥鎖錯誤的原因?

    最近使用gd32f450vg芯片,在SPI4接口上掛了gd25q32,想使用dfs文件系統(tǒng),gd25q32能夠正常的識別,顯示文件系統(tǒng)掛載正常,但是只要操作文件系統(tǒng)就會出現(xiàn)報錯,看像是互斥鎖的問題,請問這個要從哪個方向查原因
    發(fā)表于 03-05 07:39

    請問CYW43012支持DFS/雷達嗎?

    CYW43012是否支持DFS/雷達? 通過字符串命令檢查了 fmac 包中的所有固件后,它似乎不支持。 我在固件標簽中找不到-dfsradar。
    發(fā)表于 03-01 09:33

    CYW4373是否支持 ETSI EN301893中指定的 DFS(動態(tài)頻率選擇)?

    CYW4373是否支持 ETSI EN301893中指定的 DFS(動態(tài)頻率選擇)?
    發(fā)表于 03-01 08:32

    接觸器不吸合,如何用萬用表判斷接觸器線圈的好壞?

    接觸器不吸合,如何用萬用表判斷接觸器線圈的好壞? 接觸器是電氣控制裝置中常見的一種,廣泛應用于電動機的起動、制動和轉(zhuǎn)向等電力系統(tǒng)中。然而,在長時間使用過程中,接觸器的線圈可能會出現(xiàn)老化、磨損等
    的頭像 發(fā)表于 02-18 14:52 ?3088次閱讀

    TC233/TC234系列中的HSM硬件支持哪些加密算法

    HSM 中支持的算法:你能否具體說明 TC233/TC234 系列中的 HSM 硬件支持哪些加密算法? 特別是,我有興趣了解對 AES、CMAC、RSA、ECC 和 SHA 的支持。 2. 具有類似
    發(fā)表于 01-18 10:33

    mini57系列運行帶算法庫的程序,編譯沒有錯誤但無法運行是為什么?

    我用mini57系列的芯片跑做一個心率檢測的產(chǎn)品。加入心率算法庫后,發(fā)現(xiàn)程序無法運行,但是編譯沒有報錯。我在線仿真發(fā)現(xiàn)無法進入main函數(shù),程序運行不了。算法庫是用新塘的demo在keil的環(huán)境下生成的。 不知道是為什么。
    發(fā)表于 01-15 08:33
    主站蜘蛛池模板: 花怜write. as| 97大香伊在人人线色| 一级毛片免费不卡直观看| 国产精品波多野结衣| 高h道具触手play肉男男| 免费视频一区二区性色| 午夜免费福利网站| 亚洲天堂视频一区| 日本午夜三级| 天天射天天操天天| 亚洲免费毛片| 欧美一级别| 视频午夜| 久久99热精品这里久久精品| 男人边吃奶边爱边做视频日韩| 天天在线免费视频| 日本一卡精品视频免费| 欧美福利精品| 欧美一级特黄aaaaaa在线看片 | 九九视频这里只有精品| 岛国毛片在线观看| 黄色a级免费| 888xxxx免费视频| 四虎影院一区二区| 亚洲综合色网站| 少妇被按摩| 黄色在线视频免费| 小草影院亚洲私人影院| 色妇影院| 天天鲁天天爽精品视频| 国产美女精品一区二区三区| 韩国三级hd中文字幕久久精品| sss欧美华人整片在线观看| 四虎影在线永久免费观看| 羞羞影院男女午夜爽爽影视| 美女扒开尿口给男人看的让 | 成 人在线观看视频网站| tube4欧美最新69| 美女被免费视频网站九色| 国产免费资源| 日本天堂影院|