面試常問(wèn)的小算法總結(jié)

在這里插入圖片描述

前言

本文快速回顧了面試??嫉乃惴?,用作面試復(fù)習(xí),事半功倍。

需要說(shuō)明的是,由于算法的代碼實(shí)現(xiàn)主要注重思路的清晰,下方有代碼實(shí)現(xiàn)的文章主要以Python為主,Java為輔,對(duì)于Python薄弱的同學(xué)敬請(qǐng)不用擔(dān)心,幾乎可以看作是偽代碼,可讀性比較好。如實(shí)在有困難可以自行搜索Java代碼

此外,關(guān)于算法的文章之后也會(huì)單獨(dú)開(kāi)設(shè)算法專欄進(jìn)行總結(jié),敬請(qǐng)期待。

面試知識(shí)點(diǎn)復(fù)習(xí)手冊(cè)

全復(fù)習(xí)手冊(cè)文章導(dǎo)航

全復(fù)習(xí)手冊(cè)文章導(dǎo)航(CSDN)

已發(fā)布知識(shí)點(diǎn)復(fù)習(xí)手冊(cè)

-----正文開(kāi)始-----

圖的最短路徑算法

Floyd最短路算法(多源最短路)

參考:https://www.cnblogs.com/ahalei/p/3622328.html

在這里插入圖片描述

上圖中有4個(gè)城市8條公路,公路上的數(shù)字表示這條公路的長(zhǎng)短。請(qǐng)注意這些公路是單向的。我們現(xiàn)在需要求任意兩個(gè)城市之間的最短路程,也就是求任意兩個(gè)點(diǎn)之間的最短路徑。這個(gè)問(wèn)題這也被稱為“多源最短路徑”問(wèn)題。

現(xiàn)在需要一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)圖的信息,我們?nèi)匀豢梢杂靡粋€(gè)4*4的矩陣(二維數(shù)組e)來(lái)存儲(chǔ)。

在這里插入圖片描述

核心代碼:

for(k=1;k<=n;k++)
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            if(e[i][j]>e[i][k]+e[k][j])
                 e[i][j]=e[i][k]+e[k][j];

這段代碼的基本思想就是:

最開(kāi)始只允許經(jīng)過(guò)1號(hào)頂點(diǎn)進(jìn)行中轉(zhuǎn),接下來(lái)只允許經(jīng)過(guò)1和2號(hào)頂點(diǎn)進(jìn)行中轉(zhuǎn)……允許經(jīng)過(guò)1~n號(hào)所有頂點(diǎn)進(jìn)行中轉(zhuǎn),求任意兩點(diǎn)之間的最短路程。用一句話概括就是:從i號(hào)頂點(diǎn)到j(luò)號(hào)頂點(diǎn)只經(jīng)過(guò)前k號(hào)點(diǎn)的最短路程。

Dijkstra最短路算法(單源最短路)

參考:http://blog.51cto.com/ahalei/1387799

指定一個(gè)點(diǎn)(源點(diǎn))到其余各個(gè)頂點(diǎn)的最短路徑,也叫做“單源最短路徑”。例如求下圖中的1號(hào)頂點(diǎn)到2、3、4、5、6號(hào)頂點(diǎn)的最短路徑。

在這里插入圖片描述

仍然使用二維數(shù)組e來(lái)存儲(chǔ)頂點(diǎn)之間邊的關(guān)系,初始值如下。

在這里插入圖片描述

我們還需要用一個(gè)一維數(shù)組dis來(lái)存儲(chǔ)1號(hào)頂點(diǎn)到其余各個(gè)頂點(diǎn)的初始路程,如下。

在這里插入圖片描述

將此時(shí)dis數(shù)組中的值稱為最短路的“估計(jì)值”。

既然是求1號(hào)頂點(diǎn)到其余各個(gè)頂點(diǎn)的最短路程,那就先找一個(gè)離1號(hào)頂點(diǎn)最近的頂點(diǎn)。通過(guò)數(shù)組dis可知當(dāng)前離1號(hào)頂點(diǎn)最近是2號(hào)頂點(diǎn)。當(dāng)選擇了2號(hào)頂點(diǎn)后,dis[2]的值就已經(jīng)從“估計(jì)值”變?yōu)榱恕按_定值”,即1號(hào)頂點(diǎn)到2號(hào)頂點(diǎn)的最短路程就是當(dāng)前dis[2]值。

既然選了2號(hào)頂點(diǎn),接下來(lái)再來(lái)看2號(hào)頂點(diǎn)有哪些出邊呢。有2->3和2->4這兩條邊。先討論通過(guò)2->3這條邊能否讓1號(hào)頂點(diǎn)到3號(hào)頂點(diǎn)的路程變短。也就是說(shuō)現(xiàn)在來(lái)比較dis[3]和dis[2]+e[2][3]的大小。其中dis[3]表示1號(hào)頂點(diǎn)到3號(hào)頂點(diǎn)的路程。dis[2]+e[2][3]中dis[2]表示1號(hào)頂點(diǎn)到2號(hào)頂點(diǎn)的路程,e[2][3]表示2->3這條邊。所以dis[2]+e[2][3]就表示從1號(hào)頂點(diǎn)先到2號(hào)頂點(diǎn),再通過(guò)2->3這條邊,到達(dá)3號(hào)頂點(diǎn)的路程。

這個(gè)過(guò)程有個(gè)專業(yè)術(shù)語(yǔ)叫做“松弛”。松弛完畢之后dis數(shù)組為:

在這里插入圖片描述

接下來(lái),繼續(xù)在剩下的3、4、5和6號(hào)頂點(diǎn)中,選出離1號(hào)頂點(diǎn)最近的頂點(diǎn)4,變?yōu)榇_定值,以此類推。

在這里插入圖片描述

最終dis數(shù)組如下,這便是1號(hào)頂點(diǎn)到其余各個(gè)頂點(diǎn)的最短路徑。

在這里插入圖片描述
//Dijkstra算法核心語(yǔ)句
    for(i=1;i<=n-1;i++)
    {
        //找到離1號(hào)頂點(diǎn)最近的頂點(diǎn)
        min=inf;
        for(j=1;j<=n;j++)
        {
            if(book[j]==0 && dis[j]<min)
            {
                min=dis[j];
                u=j;
            }
        }
        book[u]=1;
        for(v=1;v<=n;v++)
        {
            if(e[u][v]<inf)
            {
                if(dis[v]>dis[u]+e[u][v])
                    dis[v]=dis[u]+e[u][v];
            }
        }
    }
  • M:邊的數(shù)量

  • N:節(jié)點(diǎn)數(shù)量

通過(guò)上面的代碼我們可以看出,這個(gè)算法的時(shí)間復(fù)雜度是O(N^2)。其中每次找到離1號(hào)頂點(diǎn)最近的頂點(diǎn)的時(shí)間復(fù)雜度是O(N)

優(yōu)化:

  • 這里我們可以用“堆”(以后再說(shuō))來(lái)優(yōu)化,使得這一部分的時(shí)間復(fù)雜度降低到O(logN)。

  • 另外對(duì)于邊數(shù)M少于N2的稀疏圖來(lái)說(shuō)(我們把M遠(yuǎn)小于N2的圖稱為稀疏圖,而M相對(duì)較大的圖稱為稠密圖),我們可以用鄰接表來(lái)代替鄰接矩陣,使得整個(gè)時(shí)間復(fù)雜度優(yōu)化到O( (M+N)logN)。

  • 請(qǐng)注意!在最壞的情況下M就是N2,這樣的話MlogN要比N2還要大。但是大多數(shù)情況下并不會(huì)有那么多邊,因此(M+N)logN要比N2小很多。

用鄰接表代替鄰接矩陣存儲(chǔ)

參考:http://blog.51cto.com/ahalei/1391988

略微難懂,請(qǐng)參考原文

總結(jié)如下:

可以發(fā)現(xiàn)使用鄰接表來(lái)存儲(chǔ)圖的時(shí)間空間復(fù)雜度是O(M),遍歷每一條邊的時(shí)間復(fù)雜度是也是O(M)。如果一個(gè)圖是稀疏圖的話,M要遠(yuǎn)小于N^2。因此稀疏圖選用鄰接表來(lái)存儲(chǔ)要比鄰接矩陣來(lái)存儲(chǔ)要好很多。

漢諾塔

參考圖例:https://www.zhihu.com/question/24385418/answer/89435529

關(guān)鍵代碼:

def move(n,a,b,c):
    if n == 1:
        print(a, "--->", c)
    else:
        move(n-1,a,c,b)
        print(a, "--->", c)
        move(n-1,b,a,c)

楊輝三角

參考:https://blog.csdn.net/zmy_3/article/details/51173580

關(guān)鍵代碼(巧用python中的yield):

注釋:N加上一個(gè)0之后,最后一個(gè)數(shù)是1+0,直接就等于1,不會(huì)有0

def triangles():
    N=[1]
    while True:
        yield N
        N.append(0)
        N=[N[i-1] + N[i] for i in range(len(N))]
        
n=0
for t in triangles():
    print(t)
    n=n+1
    if n == 10:
        break

回文數(shù)/回文串

解法一:暴力

return a == a[::-1]

解法二:分字符串和數(shù)字

# 字符串/數(shù)字
a = len(s)
i = 0
while i <= (a/2):
    if s[i] == s[a-1-i]:
        i += 1
    else:
        return False
return True

# 數(shù)字
def isPalindrome(x):
        if x < 0:
            return False
        temp = x 
        y = 0 
        while temp:
            y = y*10 + temp%10
            temp /= 10
        return x == y

斐波拉契數(shù)列(Fibonacci)

def fibonacci():  # 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
    f = [0] * MAXSIZE
    f[0] = 1
    f[1] = 1
    for i in range(2, MAXSIZE):
        f[i] = f[i-1] + f[i-2]
    return f
fibs = [1,1]  
for i in range(8):
    fibs.append(fibs[-2] + fibs[-1])

最大子序列與最大子矩陣問(wèn)題

數(shù)組的最大子序列問(wèn)題

給定一個(gè)數(shù)組,其中元素有正,也有負(fù),找出其中一個(gè)連續(xù)子序列,使和最大。

參考自己的博客:https://blog.csdn.net/qqxx6661/article/details/78167981

可以理解為動(dòng)態(tài)規(guī)劃:

dp[i] = dp[i-1] + s[i] (dp[i-1] >= 0)
dp[i] = s[i] (dp[i-1] < 0)

可以用標(biāo)準(zhǔn)動(dòng)態(tài)規(guī)劃求解也可以用直接方法求解,但思路都是動(dòng)態(tài)規(guī)劃

最大子矩陣問(wèn)題

給定一個(gè)矩陣(二維數(shù)組),其中數(shù)據(jù)有大有小,請(qǐng)找一個(gè)子矩陣,使得子矩陣的和最大,并輸出這個(gè)和。

參考:https://blog.csdn.net/kavu1/article/details/50547401

思路:

原始矩陣可以是二維的。假設(shè)原始矩陣是一個(gè)3 * n 的矩陣,那么它的子矩陣可以是 1 * k, 2 * k, 3 * k,(1 <= k <= n)。 如果是1*K,這里有3種情況:子矩陣在第一行,子矩陣在第二行,子矩陣在第三行。如果是 2 * k,這里有兩種情況,子矩陣在第一、二行,子矩陣在第二、三行。如果是3 * k,只有一種情況。

為了能夠找出最大的子矩陣,我們需要考慮所有的情況。假設(shè)這個(gè)子矩陣是 2 * k, 也就是說(shuō)它只有兩行,要找出最大子矩陣,我們要從左到右不斷的遍歷才能找出在這種情況下的最大子矩陣。如果我們把這兩行上下相加,情況就和求“最大子段和問(wèn)題” 又是一樣的了。

KMP算法

原理參考:

http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

移動(dòng)位數(shù) = 已匹配的字符數(shù) - 對(duì)應(yīng)的部分匹配值

"部分匹配值"就是"前綴"和"后綴"的最長(zhǎng)的共有元素的長(zhǎng)度。以"ABCDABD"為例,

- "A"的前綴和后綴都為空集,共有元素的長(zhǎng)度為0;

- "AB"的前綴為[A],后綴為[B],共有元素的長(zhǎng)度為0;

- "ABC"的前綴為[A, AB],后綴為[BC, C],共有元素的長(zhǎng)度0;

- "ABCD"的前綴為[A, AB, ABC],后綴為[BCD, CD, D],共有元素的長(zhǎng)度為0;

- "ABCDA"的前綴為[A, AB, ABC, ABCD],后綴為[BCDA, CDA, DA, A],共有元素為"A",長(zhǎng)度為1;

- "ABCDAB"的前綴為[A, AB, ABC, ABCD, ABCDA],后綴為[BCDAB, CDAB, DAB, AB, B],共有元素為"AB",長(zhǎng)度為2;

- "ABCDABD"的前綴為[A, AB, ABC, ABCD, ABCDA, ABCDAB],后綴為[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的長(zhǎng)度為0。

實(shí)現(xiàn)參考自己的博客:

https://blog.csdn.net/qqxx6661/article/details/79583707

LCS/最長(zhǎng)公共子序列/最長(zhǎng)公共子串

參考自己的博客:

https://blog.csdn.net/qqxx6661/article/details/79587392

最長(zhǎng)公共子序列LCS

動(dòng)態(tài)規(guī)劃狀態(tài)轉(zhuǎn)移方程式

在這里插入圖片描述

最長(zhǎng)公共回文子串

動(dòng)態(tài)規(guī)劃狀態(tài)轉(zhuǎn)移方程式

在這里插入圖片描述

求圓周率

在這里插入圖片描述
from random import random
from math import  sqrt
from time import clock  #計(jì)算程序運(yùn)行時(shí)間
DARTS=1200   #拋灑點(diǎn)的個(gè)數(shù)
#DARTS=5000
#DARTS=20000
#DARTS=1000000
hists=0    #拋灑點(diǎn)在1/4(半徑為1)圓內(nèi)點(diǎn)的個(gè)數(shù)
clock()
for i in range(1,DARTS):
    x,y=random(),random()
    dict=sqrt(x**2+y**2)
    if dict<=1.0:
        hists=hists+1    #隨機(jī)設(shè)點(diǎn),若拋灑點(diǎn)在1/4圓內(nèi),則dice+1
pi=4*(hists/DARTS)
print("PI的值是 %s" %pi)
print("程序運(yùn)行的時(shí)間是 %-5.5ss" %clock())

大數(shù)問(wèn)題(加減乘除)

加法

對(duì)應(yīng)位置相加,考慮進(jìn)位,前面不夠補(bǔ)0

L1 = "2649821731631836529481632803462831616487712734074314936141303241873417434716340124362304724324324324324323412121323164329751831"
L2 = "1045091731748365195814509145981509438583247509149821493213241431431319999999999999999999999999999999999999999999999999341344779"

# 長(zhǎng)度強(qiáng)行扭轉(zhuǎn)到一致,不夠前面補(bǔ)0
max_len = len(L1) if len(L1) > len(L2) else len(L2)
l1 = L1.zfill(max_len)
l2 = L2.zfill(max_len)

a1 = list(l1)
a2 = list(l2)

# 99+99最大3位所以多一位
result_list = [0] * (max_len + 1)

# 長(zhǎng)度一致 每個(gè)對(duì)應(yīng)的位置的相加的和 %10 前一位補(bǔ)1 如果>10 否則0  
for index in range(max_len - 1, -1, -1):
    index_sum = result_list[index + 1] + int(a1[index]) + int(a2[index])
    less = index_sum - 10
    result_list[index + 1] = index_sum % 10
    result_list[index] = 1 if less >= 0 else 0
    
# 若第一位為0,去除
if result_list[0] == 0:
    result_list.pop(0)

# 轉(zhuǎn)為str的list
result = [str(i) for i in result_list]
print(''.join(result))

減法

和相加十分類似

就是按照我們手寫除法時(shí)的方法,兩個(gè)數(shù)字末位對(duì)齊,從后開(kāi)始,按位相減,不夠減時(shí)向前位借一。
最終結(jié)果需要去除首端的0.如果所有位都是0,則返回0。

乘法

大數(shù)乘法問(wèn)題及其高效算法:

https://blog.csdn.net/u010983881/article/details/77503519

方法:

  1. 模擬小學(xué)乘法:最簡(jiǎn)單的乘法豎式手算的累加型;

自己實(shí)現(xiàn)的:https://blog.csdn.net/qqxx6661/article/details/78119074

  1. 分治乘法:最簡(jiǎn)單的是Karatsuba乘法,一般化以后有Toom-Cook乘法;

見(jiàn)下方

  1. 快速傅里葉變換FFT:(為了避免精度問(wèn)題,可以改用快速數(shù)論變換FNTT),時(shí)間復(fù)雜度O(N lgN lglgN)。具體可參照Sch?nhage–Strassen algorithm;
  2. 中國(guó)剩余定理:把每個(gè)數(shù)分解到一些互素的模上,然后每個(gè)同余方程對(duì)應(yīng)乘起來(lái)就行;
  3. Furer’s algorithm:在漸進(jìn)意義上FNTT還快的算法。不過(guò)好像不太實(shí)用,本文就不作介紹了。大家可以參考維基百科

方法2:

參考:

https://blog.csdn.net/jeffleo/article/details/53446095

Karatsuba乘法(公式和下面代碼實(shí)現(xiàn)的不同,但是原理相同,可以直接背下方代碼)

在這里插入圖片描述

核心語(yǔ)句:

long z2 = karatsuba(a, c);
long z0 = karatsuba(b, d);
long z1 = karatsuba((a + b), (c + d)) - z0 - z2;

return (long)(z2 * Math.pow(10, (2*halfN)) + z1 * Math.pow(10, halfN) + z0);

完整代碼:

/**
 * Karatsuba乘法
 */
public static long karatsuba(long num1, long num2){
    //遞歸終止條件
    if(num1 < 10 || num2 < 10) return num1 * num2;

    // 計(jì)算拆分長(zhǎng)度
    int size1 = String.valueOf(num1).length();
    int size2 = String.valueOf(num2).length();
    int halfN = Math.max(size1, size2) / 2;

    /* 拆分為a, b, c, d */
    long a = Long.valueOf(String.valueOf(num1).substring(0, size1 - halfN));
    long b = Long.valueOf(String.valueOf(num1).substring(size1 - halfN));
    long c = Long.valueOf(String.valueOf(num2).substring(0, size2 - halfN));
    long d = Long.valueOf(String.valueOf(num2).substring(size2 - halfN));

    // 計(jì)算z2, z0, z1, 此處的乘法使用遞歸
    long z2 = karatsuba(a, c);
    long z0 = karatsuba(b, d);
    long z1 = karatsuba((a + b), (c + d)) - z0 - z2;

    return (long)(z2 * Math.pow(10, (2*halfN)) + z1 * Math.pow(10, halfN) + z0);
}

除法

Leetcode原題(用位運(yùn)算加速了手動(dòng)除法)

https://blog.csdn.net/qqxx6661/article/details/79723357

為了加速運(yùn)算,可以依次將被除數(shù)減去1,2,4,8,..倍的除數(shù),本質(zhì)上只是用位運(yùn)算加速了手動(dòng)除法

計(jì)算機(jī)計(jì)算乘除法的原理

位運(yùn)算除法

https://blog.csdn.net/zdavb/article/details/47108505

最小生成樹

圖解Prim算法和Kruskal算法:

https://www.cnblogs.com/biyeymyhjob/archive/2012/07/30/2615542.html

兩種方法的時(shí)間復(fù)雜度

Prim:

這里記頂點(diǎn)數(shù)v,邊數(shù)e

  • 鄰接矩陣:O(v2)
  • 鄰接表:O(elog2v)

Kruskal:

elog2e e為圖中的邊數(shù)

# coding=utf-8
import sys


class Graph(object):
    def __init__(self, maps):
        self.maps = maps
        self.nodenum = self.get_nodenum()
        self.edgenum = self.get_edgenum()

    def get_nodenum(self):
        return len(self.maps)

    def get_edgenum(self):
        count = 0
        for i in range(self.nodenum):
            for j in range(i):
                if self.maps[i][j] > 0 and self.maps[i][j] < 9999:
                    count += 1
        return count

    def kruskal(self):
        res = []
        if self.nodenum <= 0 or self.edgenum < self.nodenum - 1:
            return res
        edge_list = []
        for i in range(self.nodenum):
            for j in range(i, self.nodenum):
                if self.maps[i][j] < 9999:
                    edge_list.append([i, j, self.maps[i][j]])  # 按[begin, end, weight]形式加入
        edge_list.sort(key=lambda a: a[2])  # 已經(jīng)排好序的邊集合

        group = [[i] for i in range(self.nodenum)]
        for edge in edge_list:
            for i in range(len(group)):
                if edge[0] in group[i]:
                    m = i
                if edge[1] in group[i]:
                    n = i
            if m != n:
                res.append(edge)
                group[m] = group[m] + group[n]
                group[n] = []
        return res

    def prim(self):
        res = []
        if self.nodenum <= 0 or self.edgenum < self.nodenum - 1:
            return res
        res = []
        seleted_node = [0]
        candidate_node = [i for i in range(1, self.nodenum)]

        while len(candidate_node) > 0:
            begin, end, minweight = 0, 0, 9999
            for i in seleted_node:
                for j in candidate_node:
                    if self.maps[i][j] < minweight:
                        minweight = self.maps[i][j]
                        begin = i
                        end = j
            res.append([begin, end, minweight])
            seleted_node.append(end)
            candidate_node.remove(end)
        return res

if __name__ == "__main__":
    # 讀取第一行的n
    n = int(sys.stdin.readline().strip(''))
    cun_list = list(map(int,sys.stdin.readline().strip('').split(' ')))
    dp = [[0 for __ in range(n)] for __ in range(n)]
    for i in range(n):
        for j in range(n):
            if i == j:
                dp[i][j] = 0
                continue
            dp[i][j] = max(cun_list[i],cun_list[j])


    print(dp)

    graph = Graph(dp)
    # print('鄰接矩陣為\n%s' % graph.maps)
    # print('節(jié)點(diǎn)數(shù)據(jù)為%d,邊數(shù)為%d\n' % (graph.nodenum, graph.edgenum))
    # print('------最小生成樹kruskal算法------')
    # print(graph.kruskal())
    # print('------最小生成樹prim算法')
    # print(graph.prim())
    print()

-----正文結(jié)束-----

關(guān)注我

我是蠻三刀把刀,目前為后臺(tái)開(kāi)發(fā)工程師。主要關(guān)注后臺(tái)開(kāi)發(fā),網(wǎng)絡(luò)安全,Python爬蟲等技術(shù)。

來(lái)微信和我聊聊:yangzd1102

Github:https://github.com/qqxx6661

原創(chuàng)博客主要內(nèi)容

  • 筆試面試復(fù)習(xí)知識(shí)點(diǎn)手冊(cè)
  • Leetcode算法題解析(前150題)
  • 劍指offer算法題解析
  • Python爬蟲相關(guān)技術(shù)分析和實(shí)戰(zhàn)
  • 后臺(tái)開(kāi)發(fā)相關(guān)技術(shù)分析和實(shí)戰(zhàn)

同步更新以下博客

1. Csdn

http://blog.csdn.net/qqxx6661

擁有專欄:Leetcode題解(Java/Python)、Python爬蟲開(kāi)發(fā)、面試助攻手冊(cè)

2. 知乎

https://www.zhihu.com/people/yang-zhen-dong-1/

擁有專欄:碼農(nóng)面試助攻手冊(cè)

3. 掘金

https://juejin.im/user/5b48015ce51d45191462ba55

4. 簡(jiǎn)書

http://www.itdecent.cn/u/b5f225ca2376

個(gè)人公眾號(hào):Rude3Knife

個(gè)人公眾號(hào):Rude3Knife

如果文章對(duì)你有幫助,不妨收藏起來(lái)并轉(zhuǎn)發(fā)給您的朋友們~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容