精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

求解“微信群覆蓋”的三種方法:暴力,染色,鏈表,并查集

開發 開發工具
這是一篇聊算法的文章,從一個小面試題開始,擴展到一系列基礎算法,包含以下幾個部分。

這是一篇聊算法的文章,從一個小面試題開始,擴展到一系列基礎算法,包含幾個部分:

(1) 題目簡介;

(2) 思路一:暴力法;

(3) 思路二:染色法;

(4) 思路三:鏈表法;

(5) 思路四:并查集法。

除了聊方案,重點分享思考過程。文章較長,可提前收藏。

[[439593]]

第一部分:題目簡介

問題提出:求微信群覆蓋

微信有很多群,現進行如下抽象:

(1) 每個微信群由一個唯一的gid標識;

(2) 微信群內每個用戶由一個唯一的uid標識;

(3) 一個用戶可以加入多個群;

(4) 群可以抽象成一個由不重復uid組成的集合,例如:

  • g1{u1, u2, u3}
  • g2{u1, u4, u5}

可以看到,用戶u1加入了g1與g2兩個群。

畫外音:

  • gid和uid都是uint64;
  • 集合內沒有重復元素;

假設微信有M個群(M為億級別),每個群內平均有N個用戶(N為十級別).

現在要進行如下操作:

(1) 如果兩個微信群中有相同的用戶,則將兩個微信群合并,并生成一個新微信群;

例如,上面的g1和g2就會合并成新的群:

g3{u1, u2, u3, u4, u5};

畫外音:集合g1中包含u1,集合g2中包含u1,合并后的微信群g3也只包含一個u1。

(2) 不斷的進行上述操作,直到剩下所有的微信群都不含相同的用戶為止;

將上述操作稱:求群的覆蓋。

設計算法,求群的覆蓋,并說明算法時間與空間復雜度。

畫外音:你遇到過類似的面試題嗎?

對于一個復雜的問題,思路肯定是“先解決,再優化”,大部分人不是神,很難一步到位。先用一種比較“笨”的方法解決,再看“笨方法”有什么痛點,優化各個痛點,不斷升級方案。

第二部分:暴力法

拿到這個問題,很容易想到的思路是:

(1) 先初始化M個集合,用集合來表示微信群gid與用戶uid的關系;

(2) 找到哪兩個(哪些)集合需要合并;

(3) 接著,進行集合的合并;

(4) 迭代步驟二和步驟三,直至所有集合都沒有相同元素,算法結束;

第一步,如何初始化集合?

set這種數據結構,大家用得很多,來表示集合:

(1) 新建M個set來表示M個微信群gid;

(2) 每個set插入N個元素來表示微信群中的用戶uid;

set有兩種最常見的實現方式,一種是樹型set,一種是哈希型set。

假設有集合:

s={7, 2, 0, 14, 4, 12}

樹型set的實現如下:

其特點是:

  • 插入和查找的平均時間復雜度是O(lg(n));
  • 能實現有序查找;
  • 省空間;

哈希型set實現如下:

其特點是:

  • 插入和查找的平均時間復雜度是O(1);
  • 不能實現有序查找;

畫外音:求群覆蓋,哈希型實現的初始化更快,復雜度是O(M*N)。

第二步,如何判斷兩個(多個)集合要不要合并?

集合對set(i)和set(j),判斷里面有沒有重復元素,如果有,就需要合并,判重的偽代碼是:

  1. // 對set(i)和set(j)進行元素判斷并合并 
  2. (1)    foreach (element in set(i)) 
  3. (2)    if (element in set(j)) 
  4.          merge(set(i), set(j)); 

第一行(1)遍歷第一個集合set(i)中的所有元素element;

畫外音:這一步的時間復雜度是O(N)。

第二行(2)判斷element是否在第二個集合set(j)中;

畫外音:如果使用哈希型set,第二行(2)的平均時間復雜度是O(1)。

這一步的時間復雜度至少是O(N)*O(1)=O(N)。

第三步,如何合并集合?

集合對set(i)和set(j)如果需要合并,只要把一個集合中的元素插入到另一個集合中即可:

  1. // 對set(i)和set(j)進行集合合并 
  2. merge(set(i), set(j)){ 
  3. (1)    foreach (element in set(i)) 
  4. (2)    set(j).insert(element); 

第一行(1)遍歷第一個集合set(i)中的所有元素element;

畫外音:這一步的時間復雜度是O(N)。

第二行(2)把element插入到集合set(j)中;

畫外音:如果使用哈希型set,第二行(2)的平均時間復雜度是O(1)。

這一步的時間復雜度至少是O(N)*O(1)=O(N)。

第四步:迭代第二步與第三步,直至結束

對于M個集合,暴力針對所有集合對,進行重復元素判斷并合并,用兩個for循環可以暴力解決:

  1. (1)for(i = 1 to M) 
  2. (2)    for(ji+1 to M) 
  3.          //對set(i)和set(j)進行元素判斷并合并 
  4.          foreach (element in set(i)) 
  5.          if (element in set(j)) 
  6.          merge(set(i), set(j)); 

遞歸調用,兩個for循環,復雜度是O(M*M)。

綜上,如果這么解決群覆蓋的問題,時間復雜度至少是:

  1. O(M*N) // 集合初始化的過程 
  2. O(M*M) // 兩重for循環遞歸 
  3. O(N) // 判重 
  4. O(N) // 合并 

畫外音:實際復雜度要高于這個,隨著集合的合并,集合元素會越來越多,判重和合并的成本會越來越高。

第三部分:染色法

總的來說,暴力法效率非常低,集合都是一個一個合并的,同一個元素在合并的過程中要遍歷很多次。很容易想到一個優化點,能不能一次合并多個集合?

暴力法中,判斷兩個集合se<i>t和set<j>是否需要合并,思路是:遍歷set中的所有element,看在set中是否存在,如果存在,說明存在交集,則需要合并。

哪些集合能夠一次性合并?

當某些集合中包含同一個元素時,可以一次性合并。

怎么一次性發現,哪些集合包含同一個元素,并合并去重呢?

回顧一下工作中的類似需求:

M個文件,每個文件包含N個用戶名,或者N個手機號,如何合并去重?

最常見的玩法是:

  1. cat file_1 file_2 … file_M | sort | uniq > result 

這里的思路是什么?

(1) 把M*N個用戶名/手機號輸出;

(2) sort排序,排序之后相同的元素會相鄰;

(3) uniq去重,相鄰元素如果相同只保留一個;

“排序之后相同的元素會相鄰”,就是一次性找出所有可合并集合的關鍵,這是染色法的核心。

舉一個栗子:

假設有6個微信群,每個微信群有若干個用戶:

  1. s1={1,0,5} s2={3,1} s3={2,9} 
  2. s4={4,6} s5={4,7} s6={1,8} 

假設使用樹形set來表示集合。

首先,給同一個集合中的所有元素染上相同的顏色,表示來自同一個集合。

然后,對所有的元素進行排序,會發現:

(1) 相同的元素一定相鄰,并且一定來自不同的集合;

(2) 同一個顏色的元素被打散了;

這些相鄰且相同的元素,來自哪一個集合,這些集合就是需要合并的,如上圖:

(1) 粉色的1來自集合s1,紫色的1來自集合s2,黃色的1來自集合s6,所以s1s2s6需要合并;

(2) 藍色的4來自集合s4,青色的4來自集合s5,所以s4s5需要合并;

不用像暴力法遍歷所有的集合對,而是一個排序動作,就能找到所有需要合并的集合。

畫外音:暴力法一次處理2個集合,染色法一次可以合并N個集合。

 

集合合并的過程,可以想象為,相同相鄰元素所在集合,染成第一個元素的顏色:

(1) 紫色和黃色,染成粉色;

(2) 青色,染成藍色;

最終,剩余三種顏色,也就是三個集合:

  • s1={0,1,3,5,8}
  • s3={2,9}
  • s4={4,6,7}

神奇不神奇!!!

染色法有意思么?但仍有兩個遺留問題:

(1) 粉色1,紫色1,黃色1,三個元素如何找到這三個元素所在的集合s1s2s6呢?

(2) s1s2s6三個集合如何快速合并?

畫外音:假設總元素個數n=M*N,如果使用樹形set,合并的復雜度為O(n*lg(n)),即O(M*N*lg(M*N))。

我們繼續往下看。

第四部分:鏈表法

染色法遺留了兩個問題:

  • 步驟(2)中,如何通過元素快速定位集合?
  • 步驟(3)中,如何快速合并集合?

我們繼續聊聊這兩個問題的優化思路。

問題一:如何由元素快速定位集合?

 

普通的集合,只能由集合根(root)定位元素,不能由元素逆向定位root,如何支持元素逆向定位root呢?

很容易想到,每個節點增加一個父指針即可。

更具體的:

  1. element{ 
  2.          int data; 
  3.          element* left; 
  4.          element* right; 

升級為:

  1. element{ 
  2.          element* parent;    // 指向父節點 
  3.          int data; 
  4.          element* left; 
  5.          element* right; 

如上圖:所有節點的parent都指向它的上級,而只有root->parent=NULL。

對于任意一個元素,找root的過程為:

  1. element* X_find_set_root(element* x){ 
  2.          element* temp=x
  3.          while(temp->parent != NULL){ 
  4.                    temptemp= temp->parent; 
  5.          } 
  6.          return temp; 

很容易發現,由元素找集合根的時間復雜度是樹的高度,即O(lg(n))。

有沒有更快的方法呢?

進一步思考,為什么每個節點要指向父節點,直接指向根節點是不是也可以。

更具體的:

  1. element{ 
  2.          int data; 
  3.          element* left; 
  4.          element* right; 

升級為:

  1. element{ 
  2.          element* root;         // 指向集合根 
  3.          int data; 
  4.          element* left; 
  5.          element* right; 

如上圖:所有節點的parent都指向集合的根。

對于任意一個元素,找root的過程為:

  1. element* X_find_set_root(element* x){ 
  2.          return x->root; 

很容易發現,升級后,由元素找集合根的時間復雜度是O(1)。

畫外音:不能更快了吧。

另外,這種方式,能在O(1)的時間內,判斷兩個元素是否在同一個集合內:

  1. bool in_the_same_set(element* a, element* b){ 
  2.          return (a->root == b->root); 

甚為方便。

畫外音:兩個元素的根相同,就在同一個集合內。

問題二:如何快速進行集合合并?

暴力法中提到過,集合合并的偽代碼為:

  1. merge(set(i), set(j)){ 
  2.          foreach(element in set(i)) 
  3.                    set(j).insert(element); 

把一個集合中的元素插入到另一個集合中即可。

假設set(i)的元素個數為n1,set(j)的元素個數為n2,其時間復雜度為O(n1*lg(n2))。

在“微信群覆蓋”這個業務場景下,隨著集合的不斷合并,集合高度越來越高,合并會越來越慢,有沒有更快的集合合并方式呢?

仔細回顧一下:

(1) 樹形set的優點是,支持有序查找,省空間;

(2) 哈希型set的優點是,快速插入與查找;

而“微信群覆蓋”場景對集合的頻繁操作是:

(1) 由元素找集合根;

(2) 集合合并;

那么,為什么要用樹形結構或者哈希型結構來表示集合呢?

畫外音:優點完全沒有利用上嘛。

讓我們來看看,這個場景中,如果用鏈表來表示集合會怎么樣,合并會不會更快?

  • s1={7,3,1,4}
  • s2={1,6}

如上圖,分別用鏈表來表示這兩個集合。可以看到,為了滿足“快速由元素定位集合根”的需求,每個元素仍然會指向根。

s1和s2如果要合并,需要做兩件事:

  • 集合1的尾巴,鏈向集合2的頭(藍線1);
  • 集合2的所有元素,指向集合1的根(藍線2,3);

合并完的效果是:

變成了一個更大的集合。

假設set(1)的元素個數為n1,set(2)的元素個數為n2,整個合并的過程的時間復雜度是O(n2)。

畫外音:時間耗在set(2)中的元素變化。

咦,我們發現:

(1) 將短的鏈表,接到長的鏈表上;

(2) 將長的鏈表,接到短的鏈表上;

所使用的時間是不一樣的。

為了讓時間更快,一律使用更快的方式:“元素少的鏈表”主動接入到“元素多的鏈表”的尾巴后面。這樣,改變的元素個數能更少一些,這個優化被稱作“加權合并”。

對于M個微信群,平均每個微信群N個用戶的場景,用鏈表的方式表示集合,按照“加權合并”的方式合并集合,最壞的情況下,時間復雜度是O(M*N)。

畫外音:假設所有的集合都要合并,共M次,每次都要改變N個元素的根指向,故為O(M*N)。

于是,對于“M個群,每個群N個用戶,微信群求覆蓋”問題,使用“染色法”加上“鏈表法”,核心思路三步驟:

(1) 全部元素全局排序;

(2) 全局排序后,不同集合中的相同元素,一定是相鄰的,通過相同相鄰的元素,一次性找到所有需要合并的集合;

(3) 合并這些集合,算法完成;

其中:

  • 步驟(1),全局排序,時間復雜度O(M*N);
  • 步驟(2),染色思路,能夠迅猛定位哪些集合需要合并,每個元素增加一個屬性指向集合根,實現O(1)級別的元素定位集合;
  • 步驟(3),使用鏈表表示集合,使用加權合并的方式來合并集合,合并的時間復雜度也是O(M*N);

總時間復雜度是:

  1. O(M*N)    //排序 
  2. O(1)        //由元素找到需要合并的集合 
  3. O(M*N)    //集合合并 

神奇不神奇!!!

神奇不止一種,還有其他方法嗎?我們接著往下看。

第五部分:并查集法

分離集合(disjoint set)是一種經典的數據結構,它有三類操作:

  • Make-set(a):生成一個只有一個元素a的集合;
  • Union(X, Y):合并兩個集合X和Y;
  • Find-set(a):查找元素a所在集合,即通過元素找集合;

這種數據結構特別適合用來解決這類集合合并與查找的問題,又稱為并查集。

能不能利用并查集來解決求“微信群覆蓋”問題呢?

一、并查集的鏈表實現

鏈表法里基本聊過,為了保證知識的系統性,這里再稍微回顧一下。

如上圖,并查集可以用鏈表來實現。

鏈表實現的并查集,Find-set(a)的時間復雜度是多少?

集合里的每個元素,都指向“集合的句柄”,這樣可以使得“查找元素a所在集合S”,即Find-set(a)操作在O(1)的時間內完成。

鏈表實現的并查集,Union(X, Y)的時間復雜度是多少?

假設有集合:

  • S1={7,3,1,4}
  • S2={1,6}

合并S1和S2兩個集合,需要做兩件事情:

(1) 第一個集合的尾元素,鏈向第二個集合的頭元素(藍線1);

(2) 第二個集合的所有元素,指向第一個集合的句柄(藍線2,3);

合并完的效果是:

變成了一個更大的集合S1。

集合合并時,將短的鏈表,往長的鏈表上接,這樣變動的元素更少,這個優化叫做“加權合并”。

畫外音:實現的過程中,集合句柄要存儲元素個數,頭元素,尾元素等屬性,以方便上述操作進行。

假設每個集合的平均元素個數是n,Union(X, Y)操作的時間復雜度是O(n)。

能不能Find-set(a)與Union(X, Y)都在O(1)的時間內完成呢?

可以,這就引發了并查集的第二種實現方法。

二、并查集的有根樹實現

什么是有根樹,和普通的樹有什么不同?

常用的set,就是用普通的二叉樹實現的,其元素的數據結構是:

  1. element{ 
  2.          int data; 
  3.          element* left; 
  4.          element* right; 

通過左指針與右指針,父親節點指向兒子節點。

 

而有根樹,其元素的數據結構是:

  1. element{ 
  2.          int data; 
  3.          element* parent; 

通過兒子節點,指向父親節點。

假設有集合:

  • S1={7,3,1,4}
  • S2={1,6}

通過如果通過有根樹表示,可能是這樣的:

所有的元素,都通過parent指針指向集合句柄,所有元素的Find-set(a)的時間復雜度也是O(1)。

畫外音:假設集合的首個元素,代表集合句柄。

有根樹實現的并查集,Union(X, Y)的過程如何?時間復雜度是多少?

通過有根樹實現并查集,集合合并時,直接將一個集合句柄,指向另一個集合即可。

如上圖所示,S2的句柄,指向S1的句柄,集合合并完成:S2消亡,S1變為了更大的集合。

容易知道,集合合并的時間復雜度為O(1)。

會發現,集合合并之后,有根樹的高度變高了,與“加權合并”的優化思路類似,總是把節點數少的有根樹,指向節點數多的有根樹(更確切的說,是高度矮的樹,指向高度高的樹),這個優化叫做“按秩合并”。

新的問題來了,集合合并之后,不是所有元素的Find-set(a)操作都是O(1)了,怎么辦?

如圖S1與S2合并后的新S1,首次“通過元素6來找新S1的句柄”,不能在O(1)的時間內完成了,需要兩次操作。

但為了讓未來“通過元素6來找新S1的句柄”的操作能夠在O(1)的時間內完成,在首次進行Find-set(“6”)時,就要將元素6“尋根”路徑上的所有元素,都指向集合句柄,如下圖。

某個元素如果不直接指向集合句柄,首次Find-set(a)操作的過程中,會將該路徑上的所有元素都直接指向句柄,這個優化叫做“路徑壓縮”。

畫外音:路徑上的元素第二次執行Find-set(a)時,時間復雜度就是O(1)了。

實施“路徑壓縮”優化之后,Find-set的平均時間復雜度仍是O(1)。

稍微總結一下。

通過鏈表實現并查集:

(1) Find-set的時間復雜度,是O(1)常數時間;

(2) Union的時間復雜度,是集合平均元素個數,即線性時間;

畫外音:別忘了“加權合并”優化。

通過有根樹實現并查集:

(1) Union的時間復雜度,是O(1)常數時間;

(2) Find-set的時間復雜度,通過“按秩合并”與“路徑壓縮”優化后,平均時間復雜度也是O(1);

即,使用并查集,非常適合解決“微信群覆蓋”問題。

知其然,知其所以然,思路往往比結果更重要。

算法,其實還是挺有意思的。

【本文為51CTO專欄作者“58沈劍”原創稿件,轉載請聯系原作者】

戳這里,看該作者更多好文 

 

 

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2018-11-20 14:48:22

微信群集合數據

2009-07-08 12:56:32

編寫Servlet

2010-11-12 14:00:24

Transact-SQ

2009-06-23 10:45:18

Hibernate支持

2011-06-10 10:43:12

Ubuntu應用安裝

2011-04-18 15:32:45

游戲測試測試方法軟件測試

2010-09-14 15:10:49

CSS注釋

2023-08-14 17:58:13

RequestHTTP請求

2009-12-11 18:49:39

預算編制博科資訊

2022-07-13 16:06:16

Python參數代碼

2024-11-15 07:00:00

Python發送郵件

2021-09-18 23:15:31

微信功能檢測

2022-06-19 23:39:58

機器學習數據集驗證策略

2016-10-12 13:53:38

JavaByteBufferRandomAcces

2010-09-08 13:29:48

CSS

2023-02-21 14:58:12

間序列周期數據集

2010-11-16 16:11:28

Oracle身份驗證

2020-06-17 10:52:00

DDoS攻擊網絡攻擊網絡安全

2021-07-13 12:31:27

IT組織改進首席技術官

2021-10-09 06:59:36

技術MyBatis數據
點贊
收藏

51CTO技術棧公眾號

日韩午夜电影免费看| 成人h动漫精品一区二区无码| 日韩一级电影| 欧洲一区在线电影| 9l视频自拍9l视频自拍| 婷婷五月综合激情| 久久不射网站| 欧美精品在线极品| a天堂中文字幕| 97超碰成人| 欧美日韩在线一区二区| 免费一级特黄毛片| 黄网址在线观看| 久久免费的精品国产v∧| 91九色综合久久| 国产一级免费视频| 亚洲午夜极品| 久久久av电影| 女人黄色一级片| 久久悠悠精品综合网| 91精品国产综合久久精品麻豆 | 亚洲一区二区三区免费在线观看 | 精品国产91久久久久久久妲己| 99视频免费播放| av成人福利| 亚洲免费观看高清完整版在线观看| 欧美亚洲丝袜| 日日躁夜夜躁白天躁晚上躁91| 精品亚洲成av人在线观看| 日本aⅴ大伊香蕉精品视频| 精品99久久久久成人网站免费 | 中文人妻av久久人妻18| 亚洲精品九九| 欧美激情第6页| 一级片一级片一级片| 久久密一区二区三区| 日韩av在线看| 成人性生活免费看| ccyy激情综合| 精品日韩99亚洲| japan高清日本乱xxxxx| 国产精品毛片aⅴ一区二区三区| 欧美在线观看视频一区二区三区| 欧美a v在线播放| av中文资源在线资源免费观看| 亚洲精品免费在线| 最近免费观看高清韩国日本大全| 秋霞a级毛片在线看| 中文字幕高清一区| 一区二区三区欧美成人| 日本中文字幕电影在线免费观看| 91免费视频观看| 欧美三日本三级少妇三99| 五月婷婷伊人网| 久久久久久久久免费| 欧美福利精品| аⅴ资源新版在线天堂| 国产精品麻豆一区二区| 欧美精品一区二区性色a+v| 国产视频中文字幕在线观看| 亚洲人精品午夜| avove在线观看| 国产丝袜视频在线播放| 精品电影在线观看| 欧美黄色一级片视频| 亚洲精品粉嫩美女一区| 欧美日韩中文一区| 性生活一级大片| 红杏aⅴ成人免费视频| 日韩av网站大全| 亚洲一二三四视频| 一区二区在线| 九九热在线精品视频| 可以免费看的av毛片| 日韩在线一区二区| 国产精品偷伦一区二区| 国产熟女一区二区丰满| 99在线精品视频| 婷婷久久伊人| av理论在线观看| 狠狠色狠色综合曰曰| 中文久久久久久| 日韩有吗在线观看| 亚洲精品视频播放| 欧美xxxooo| 日韩视频精品在线观看| 国产精品久久久91| 国产黄色大片网站| 久久先锋影音av| 免费看污污视频| 手机av在线| 欧美疯狂做受xxxx富婆| 久久性爱视频网站| 欧美激情电影| 4k岛国日韩精品**专区| 97caocao| 久久综合色综合88| 中文字幕の友人北条麻妃| 欧美亚洲日本精品| 6080午夜不卡| av电影网站在线观看| 欧美视频官网| 国产精品视频一区二区高潮| 老司机午夜福利视频| 中文字幕精品综合| 免费无码不卡视频在线观看| 国产精品一区二区精品| 亚洲香蕉成视频在线观看| 久草视频免费在线播放| 蜜桃视频免费观看一区| 久久精品成人一区二区三区蜜臀| 国产日产一区二区三区| 一本到不卡精品视频在线观看 | 久久久亚洲欧洲日产国码αv| 在线观看成人免费| 丁香久久综合| 亚洲激情视频网站| 色在线观看视频| 免费的成人av| 日韩欧美精品一区二区三区经典| 91福利在线免费| 欧美一区二区日韩| 少妇视频一区二区| 日韩av一区二区在线影视| 久久99精品国产一区二区三区| 婷婷色在线播放| 欧美一区中文字幕| 999精品视频在线观看播放| 日韩国产成人精品| 欧美连裤袜在线视频| 色偷偷偷在线视频播放| 亚洲第一区在线| 久久网免费视频| 国产风韵犹存在线视精品| 老汉色影院首页| 精品一区二区三区免费看| 日韩中文字幕亚洲| 国产又粗又猛又爽又黄91| 亚洲国产精华液网站w| 午夜激情福利在线| 精品视频免费| 国产美女精品视频| 91美女视频在线| 欧美精品一二三| 伊人久久久久久久久久久久久久| 免费av网站大全久久| 亚洲精品高清视频| 亚洲18在线| 欧美精品在线观看| 亚洲高清视频在线播放| 亚洲午夜日本在线观看| 日本美女视频网站| 99视频+国产日韩欧美| 精品国产乱码久久久久久郑州公司| av资源一区| 亚洲美女中文字幕| 无码人妻丰满熟妇区五十路 | 色一情一区二区三区四区| 外国电影一区二区| 色噜噜国产精品视频一区二区| 国产精品女同一区二区| 一区二区三区在线视频观看58| 性生交大片免费看l| 亚洲欧洲日本一区二区三区| 精品国产乱码一区二区三区四区 | 日韩欧美久久一区| 日韩av男人天堂| 国产午夜一区二区三区| 九九热精品国产| 亚洲无毛电影| 欧美视频观看一区| 自拍偷拍欧美日韩| 97婷婷涩涩精品一区| 国产鲁鲁视频在线观看免费| 欧美精品成人一区二区三区四区| 久操视频免费在线观看| 337p粉嫩大胆噜噜噜噜噜91av| wwwwww.色| 一本精品一区二区三区| 久久99精品久久久久久秒播放器| 视频一区在线免费看| 欧美裸身视频免费观看| 三级毛片在线免费看| 欧美日韩国产高清一区二区| 强乱中文字幕av一区乱码| 久久综合狠狠综合| 手机在线免费毛片| 夜夜爽av福利精品导航| 一区二区三区国产福利| 台湾佬综合网| 91精品国产高清久久久久久91裸体| 草草在线视频| 久久精品人人做人人爽| 天堂a√中文在线| 欧美一级黄色片| 老熟妇一区二区三区| 一区二区成人在线观看| 国产精成人品免费观看| 高清av一区二区| 五月婷婷丁香色| 一区二区黄色| 日韩精品久久一区二区| 欧美午夜精品一区二区三区电影| 懂色av一区二区三区在线播放| 日本精品另类| 91产国在线观看动作片喷水| 特级毛片在线| 日韩在线资源网| 欧美日韩视频精品二区| 精品日本一线二线三线不卡| 91在线观看喷潮| 一本色道a无线码一区v| 日韩美女一级片| 亚洲色大成网站www久久九九| 日韩中文字幕电影| av午夜一区麻豆| 可以看的av网址| 精品亚洲国内自在自线福利| 亚洲激情在线观看视频| 性色一区二区三区| 久在线观看视频| 好看的av在线不卡观看| 麻豆传媒网站在线观看| 91精品综合久久久久久久久久久| 日韩精品福利视频| 国产成人av| 蜜桃久久精品乱码一区二区| 日韩福利视频一区| 国产伦精品一区二区三区高清| 亚洲精品一二三**| 91中文字幕在线观看| 外国成人毛片| 成人免费网站在线| 99精品美女视频在线观看热舞| 国产精选久久久久久| 国内精品伊人| 国产日产欧美精品| 欧美啪啪网站| 成人精品aaaa网站| 久久伊人久久| 91久久国产综合久久蜜月精品| 日本一区二区三区电影免费观看| 亚洲www视频| 中文字幕久久精品一区二区| 岛国视频一区| 欧美黑人巨大videos精品| 国产在线一区二区三区四区 | 宅男一区二区三区| 久久久久久影院| 91大学生片黄在线观看| 亚洲大片在线| 国产免费黄视频| 天堂蜜桃91精品| 自拍偷拍一区二区三区四区| 美女国产一区二区三区| 五月六月丁香婷婷| 国产高清精品久久久久| 免费a v网站| 久久久久久夜精品精品免费| 永久免费毛片在线观看| 亚洲欧洲一区二区三区| 成人免费视频网站入口::| 亚洲在线视频免费观看| 日本少妇激情舌吻| 色成人在线视频| 国产精品一品二区三区的使用体验| 欧美一区二区免费观在线| 丰满少妇高潮在线观看| 国产网站欧美日韩免费精品在线观看| 91精品国产综合久久久久久豆腐| 久久久av亚洲男天堂| 国产乱妇乱子在线播视频播放网站| 91精品国产91久久久久久不卡| 亚洲精品永久免费视频| 国产日韩av在线| 国产乱人伦丫前精品视频| 欧美一区二区三区四区夜夜大片 | 999精品视频在线| 国产一区在线看| 中文字幕影片免费在线观看| 国产午夜精品在线观看| 日韩女优一区二区| 疯狂蹂躏欧美一区二区精品| 中文字幕在线2019| 亚洲第一精品自拍| 日本暖暖在线视频| 欧美一级电影免费在线观看| 日韩成人在线一区| 久久偷看各类wc女厕嘘嘘偷窃| 日韩理论电影院| av日韩一区二区三区| 蜜臀av亚洲一区中文字幕| 欧美极品jizzhd欧美仙踪林| 国产精品污www在线观看| 国产污视频在线看| 欧美日韩aaaaaa| 日韩在线免费看| 欧美黑人极品猛少妇色xxxxx| 天天综合网站| 国产欧美精品一区二区三区| 99久久夜色精品国产亚洲96| 国产女女做受ⅹxx高潮| 国产成人午夜精品影院观看视频 | cao在线视频| 91精品免费看| 精品成人影院| 国产资源在线视频| 国产99久久久国产精品潘金 | 国产在线日本| 久久久久在线观看| 电影中文字幕一区二区| 日本精品一区二区三区高清 久久 日本精品一区二区三区不卡无字幕 | 国产午夜福利精品| 91精品国产91久久综合桃花| 国产在线高清| 51午夜精品视频| 国产一区二区在线视频你懂的| 青青草原网站在线观看| 另类欧美日韩国产在线| 亚洲精品成人无码| 福利视频第一区| 好吊妞无缓冲视频观看| 你懂的好爽在线观看| 亚洲欧美中文日韩在线| 黑人玩欧美人三根一起进| 91免费视频网站| 国产精品97| 中文字幕中文在线| 中文字幕av一区二区三区| www.欧美色| 亚洲天堂第一页| 欧美性xxx| 欧美成人在线免费观看| 国产精品一区亚洲| 可以直接看的无码av| 福利微拍一区二区| 亚州男人的天堂| 55夜色66夜色国产精品视频| 欧美理伦片在线播放| 俄罗斯av网站| 久久嫩草精品久久久精品| 亚洲不卡在线视频| 中文字幕国产亚洲2019| 久久不卡日韩美女| 黄色www在线观看| 激情伊人五月天久久综合| 中文字幕五月天| 日韩欧美国产一区二区在线播放| 三级资源在线| 国产伦精品一区二区三区免| 中文精品视频| 欧美日韩高清丝袜| 欧美色精品在线视频| 免费超碰在线| 国产精品18毛片一区二区| 国产日韩欧美一区| 欧美黄色一级生活片| 欧美性猛片aaaaaaa做受| 日本中文在线观看| 99re国产视频| 中文欧美日韩| 青娱乐国产视频| 制服丝袜激情欧洲亚洲| 欧美性video| 欧美不卡三区| 久久99热狠狠色一区二区| 久久久久亚洲av无码专区| 日韩av有码在线| 婷婷激情成人| 国产 日韩 亚洲 欧美| 国产日韩综合av| 国产视频一区二区三区四区五区| 国语自产偷拍精品视频偷| 国产精品片aa在线观看| 亚洲一区二区三区观看| 亚洲成av人片| www.中文字幕久久久| 3d动漫精品啪啪一区二区三区免费 | 欧美大胆成人| 强伦女教师2:伦理在线观看| 丁香亚洲综合激情啪啪综合| 久久久久久无码午夜精品直播| 久久精品夜夜夜夜夜久久| 免费看久久久| 爱爱爱爱免费视频| 精品免费在线观看| 久久bbxx| 欧美日韩系列| 国产成人小视频| 中文字幕视频免费观看| 69av在线播放| 久久一本综合| 瑟瑟视频在线观看| 精品国产乱码久久久久久1区2区| 忘忧草在线www成人影院| 男人天堂av片| 《视频一区视频二区| 欧美xxx.com| 国产精品麻豆免费版| 精品在线播放午夜|