劍指offer數(shù)據(jù)結構

劍指offer線性數(shù)據(jù)結構

劍指offer是找工作開始后刷的第一本書,刷題用牛客網(wǎng)。這本書可以說是已經(jīng)總結歸納的很好了,按照 基礎知識,高質(zhì)量代碼,解決問題的思路以及優(yōu)化時間和空間的效率分成了好幾章。對于初次刷題的人很有啟發(fā)的作用,為了加深印象,決定按照 數(shù)據(jù)結構的類型/算法類型 重新整理一遍,同時加入Leetcode相同tag的題。第一遍刷題用的是C++,很多時候有些題想不到思路,得回去看書,回去翻牛客網(wǎng)的答案。總結完之后打算二刷,用Python再刷一遍。(還是Java吧,Python就是簡化版?zhèn)未a,刷了幾題之后python的確簡單)

線性數(shù)據(jù)結構

字符串類

下標的移動很關鍵. 如何移動下標使得效率高?(怎么利用冗余的信息?)

如果是插入刪除,如何使移動的次數(shù)最少?

查找如何用空間換時間?

帶特殊條件的查找類,如何控制邊界條件?

如何把問題分解為 遞歸?回溯?分治?動態(tài)規(guī)劃?

string類和char *str的區(qū)別以及string類含有什么標準函數(shù)? char* 和string的的互相變換?

回文問題

字符串的查找都見過的題以及去思科面試被兩個面試官都問過的題:判斷是不是判斷是不是回文, 雙指針即可。

變種題: 給定一個字符串,問是否能通過添加一個字母將其變?yōu)榛匚拇?/p>

思路:分析題意,本身是回文,添加一個字母一定是回文。本身不是回文,則可以允許其中一個字符不匹配,這時處理好指針的移動。結束條件,兩指針相遇。

查找子串:模式匹配算法

字符串為T,模式為P,求P是不是T的子串。

樸素/KMP/BM算法

  1. 樸素的方法為回溯的方法,如果不同,回溯,復雜度o(mn),又稱Brute Force(暴力搜索方法)。

  2. KMP(Knuth-Morris-Pratt)算法,通過增加額外的表,利用子串自己本身的信息,移動兩個指針

    本身的信息:每次不匹配時,如何移動指向pattern的指針。空間換時間的一種做法。先存下當前位置,后綴和前綴相同的長度。

  3. BM算法(Boyer-Moore)

    從后往前比較,如果相同,則雙指針向前移,如果不同,則移動的位數(shù)為該字符在子字符中出現(xiàn)的位置。 采用兩個規(guī)則,好后綴規(guī)則和壞字符規(guī)則。

    壞字符規(guī)則:如果不匹配,不存在這個字符,則整體后移,存在,則移動,使其對齊。

    好后綴規(guī)則:和KMP類似,直接移動直到對齊部分和前綴相同。

    實現(xiàn)的時候,生成兩張表,一個為壞字符移動的表,一個為好后綴移動表。

子串問題

例題1:計算兩個字符串的最大公共字串的長度,字符不區(qū)分大小寫

int getCommonStrLength(char * pFirstStr, char * pSecondStr);

看到此題聯(lián)想起生物信息課上蛋白質(zhì)序列l(wèi)ocal alignment,其實為動態(tài)規(guī)劃Dynamic Programming問題。建立數(shù)值矩陣。

例題2:對于一個字符串,請設計一個高效算法,計算其中最長回文子串的長度。

給定字符串A以及它的長度n,請返回最長回文子串的長度。

測試樣例:

"abc1234321ab",12
返回:7

思路: 將該字符串翻轉(zhuǎn),則變成例題1.

基于哈希表的查找

題目描述:題目描述

在一個字符串(0<=字符串長度<=10000,全部由字母組成)中找到第一個只出現(xiàn)一次的字符,并返回它的位置, 如果沒有則返回 -1(需要區(qū)分大小寫).

分析:這題有點和桶排序類似,直接記錄字符出現(xiàn)的次數(shù)。字符串的數(shù)值范圍[0-256]。

哈希表的知識補充:1. 根據(jù)key值,可以直接訪問value,加快存取速度。哈希表重要的幾個因素, 如果鍵值不同,值相同,稱為沖突。散列函數(shù),處理沖突,載荷因子。
collision : k1 \neq k2, f(k1) = f(k2)

字符串含特殊字符的匹配

此類題目看似簡單,但字符串的指針的移動需要特別小心。

正則表達式的匹配

請實現(xiàn)一個函數(shù)用來匹配包括'.'和''的正則表達式。模式中的字符'.'表示任意一個字符,而*表示它前面的字符可以出現(xiàn)任意次(包含0次)。 在本題中,匹配是指字符串的所有字符匹配整個模式。例如,字符串"aaa"與模式"a.a"和"ab*ac*a"匹配,但是與"aa.a"和"aba"均不匹配

分析:此題的難點再于理清思路,比較難處理的是*,因為* 是變長的,而且影響的是前面的字符。程序中最難處理的是 .*,而且前一個字符匹配成功與否與后面的*是相關的,而且也很難確定*到底有幾個。

這時用到了遞歸。 (將復雜的循環(huán)轉(zhuǎn)換為遞歸是很方便的)

當pattern+1 == * 時, return match(str,pattern+2)|| match(str+1,pattern);返回匹配0個或者匹配1個以上的時候。

表示數(shù)值的字符串

請實現(xiàn)一個函數(shù)用來判斷字符串是否表示數(shù)值(包括整數(shù)和小數(shù))。例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示數(shù)值。 但是"12e", "1a3.14", "1.2.3", "+-5"和 "12e+4.3"都不是。

分析:自動機的實現(xiàn)。自動機可以回顧研一上學的課Fundamental of CS.書籍《Logic and Language Models for Computer Science,Hamburger and Richards》 Finite Automatic Machine.

其中比較有意思的知識點事DFA和NFA, Determinstic和Non-determinstic自動機。其中NFA一個條件可以到達多種狀態(tài)。不過狀態(tài)機雖然看起來一目了然,實現(xiàn)的時候處理要很好的處理轉(zhuǎn)移給自己的狀態(tài)。

字符串中正則表達式的函數(shù)以及庫

解題的時候可以快速解答。

字符串的翻轉(zhuǎn)

例如,“student. a am I”。后來才意識到,這家伙原來把句子單詞的順序翻轉(zhuǎn)了,正確的句子應該是“I am a student.”。Cat對一一的翻轉(zhuǎn)這些單詞順序可不在行,你能幫助他么?

分析:先旋轉(zhuǎn)一遍,再找到單詞再轉(zhuǎn)一遍。

字符串轉(zhuǎn)換為整數(shù)

將一個字符串轉(zhuǎn)換成一個整數(shù)(實現(xiàn)Integer.valueOf(string)的功能,但是string不符合數(shù)字要求時返回0),要求不能使用字符串轉(zhuǎn)換整數(shù)的庫函數(shù)。 數(shù)值為0或者字符串不是一個合法的數(shù)值則返回0。

分析:按部就班 - ‘0’即可

左旋字符串

匯編語言中有一種移位指令叫做循環(huán)左移(ROL),現(xiàn)在有個簡單的任務,就是用字符串模擬這個指令的運算結果。對于一個給定的字符序列S,請你把其循環(huán)左移K位后的序列輸出。例如,字符序列S=”abcXYZdef”,要求輸出循環(huán)左移3位后的結果,即“XYZdefabc”。是不是很簡單?OK,搞定它!

分析

  1. 利用額外空間儲存的話,簡單

  2. 要是不用額外空間儲存,則翻轉(zhuǎn)即可。 前K個翻轉(zhuǎn)一次,后K個翻轉(zhuǎn)一次,再整體翻轉(zhuǎn)。
    BA = (A^TB^T)^T

大數(shù)類題目

動態(tài)規(guī)劃類

這一類題目歸結到動態(tài)規(guī)劃當中

數(shù)組類

排序

時間復雜度最壞 時間復雜度最好 時間復雜度平均 穩(wěn)定性
冒泡排序 n^2 n^2 n^2 穩(wěn)定
選擇排序 n^2 n^2 n^2 不穩(wěn)定
插入排序 n^2 n^2 n^2 穩(wěn)定
歸并排序 nlogn nlogn nlogn 穩(wěn)定
堆排序 nlogn nlogn nlogn 不穩(wěn)定
快速排序 nlogn nlogn n^2 不穩(wěn)定
希爾排序 n^1.5 n^1.3 n^2 不穩(wěn)定
桶排序 n+m n n 不穩(wěn)定
基數(shù)排序 p(n+b) p(n+b) p(n+b) 穩(wěn)定

冒泡排序,選擇排序,插入排序

這三種時間復雜大相同。

冒泡排序:二重循環(huán),和相鄰的元素比較,有點類似于水泡上升,第二重循環(huán)值為[arr.size()-1:i;-1]

選擇排序:二重循環(huán),第二重循環(huán)值為[i:arr.size()-1:1],每次選擇最小的值和i交換。

插入排序:假定前n-1個數(shù)已經(jīng)排好序,現(xiàn)在將第n個數(shù)插到前面的有序數(shù)列中,使得這n個數(shù)也是排好順序的。如此反復循環(huán),直到全部排好順序。第二重的循環(huán)值為[i+1:0,-1], 看需不需要交換

歸并排序,mergeSort

  1. 先split
  2. 再merge, merge的時候需要每次找到左邊和右邊的邊界值,需要創(chuàng)建額外的空間,然后先保存中間結果,再copy過去。
  3. 需要注意的地方,由于middle =(l+r)/2,此時分治法的遞歸函數(shù)里的左中右需要很清晰的處理,左開右閉,左閉右開,元素為1的時候返回。
  4. 外部排序?

快速排序,分治,quicksort

重要的函數(shù)為Partition函數(shù),其中還有與其類似的利用partition思想的題目。隨機選擇一個數(shù),比它大的放左邊,比它小的放右邊。

進階random quicksort

不穩(wěn)定.

class BubbleSort {
public:
    void bubbleSort(vector<int> &data) {
        for (int i = 0; i < data.size(); ++i) {
            for (int j = data.size() - 1; j > i; --j) {
                if (data[j - 1] > data[j]) {
                    swap(data[j - 1], data[j]);
                }
            }
        }
    }
};

class SelectionSort {
public:
    void selecSort(vector<int> &data) {
        for (int i = 0; i < data.size(); ++i) {
            int small = i;
            for (int j = i + 1; j < data.size(); ++j) {
                if (data[j] < data[small]) {
                    small = j;
                }
                swap(data[small], data[i]);
            }
        }
    }
};

class InsertSort {
public:
    void insertSort(vector<int> &data) {
        for (int i = 1; i < data.size(); ++i) {
            for (int j = i; j > 0; j--) {
                if (data[j - 1] > data[j]) {
                    swap(data[j - 1], data[j]);
                }
            }
        }
    }
};

class MergeSort {
public:

    void merge(vector<int> &data, int l, int m, int r) {
        int temp[r - l];
        int index = 0;
        int leftIndex = l;
        int rightIndex = m;

        while (leftIndex < m && rightIndex < r) {
            if (data[leftIndex] > data[rightIndex]) {
                temp[index++] = data[rightIndex++];

            } else {
                temp[index++] = data[leftIndex++];
            }
        }

        // copy the rest to the temp
        if (leftIndex < m) {
            while (leftIndex < m) {
                temp[index++] = data[leftIndex++];
            }
        } else {
            while (rightIndex < r) {
                temp[index++] = data[rightIndex++];
            }
        }

        // copy back
        for (int i = l; i < r; ++i) {
            data[i] = temp[i - l];
        }

    }

    void mergeSort(vector<int> &data, int l, int r) {
        // [l,r),數(shù)組大小為1的時候,即l<r-1的時候返回, 或者也可以為[l,r],則上面不等式要加等號
        if (l < r - 1) {
            int m = (l + r) / 2;
            mergeSort(data, l, m);
            mergeSort(data, m, r);
            merge(data, l, m, r);
        }
    }

};

class QuickSort {
public:
    void quickSort(vector<int> &data, int left, int right) {
        if (left < right) {
            int pi = partition(data, left, right);
            quickSort(data, left, pi - 1);
            quickSort(data, pi + 1, right);
        }
    }

    int partition(vector<int> &data, int left, int right) {
        int pivot = data[right];
        if (left < right) {
            int rightIndex = right;
            int index = right - 1;
            while (index >= left) {
                if (data[index] >= pivot) {
                  //這段代碼是有錯誤的 比如[3,1,2],1和1交換后,rightIndex卻移了.網(wǎng)上找到一段更通用的代碼12.29
                    swap(data[index], data[rightIndex - 1]);
                    rightIndex--;
                }
                index--;
            }
            swap(data[rightIndex], data[right]);
            return rightIndex;
        }
    }
};

希爾排序 Shell sort

在要排序的一組數(shù)中,根據(jù)某一增量分為若干子序列,并對子序列分別進行插入排序。
然后逐漸將增量減小,并重復上述過程。直至增量為1,此時數(shù)據(jù)序列基本有序,最后進行插入排序。時間復雜度減少

不穩(wěn)定

什么腦回路,先擱置。

  1. 增量序列+插入排序
  2. 增量序列為size/2這樣計算出來
  3. 最壞情況 O(N^2),各種間隔序列的排序沒有交換,增量序列不互質(zhì),這樣每次都不起作用(youtube上)
  4. Hibbard增量序列。D=2k-1,相鄰元素互質(zhì),T=(N3/2),avg(N^5/4)
  5. Sedgewick增量序列
  6. 依賴于增量序列的選擇,跳著排,不穩(wěn)定。

計數(shù)排序

有點類似與哈希表的感覺,適用于海量數(shù)據(jù)并且數(shù)據(jù)值在一定范圍內(nèi)的時候。

基數(shù)排序Radix Sort創(chuàng)建10個桶,再從個位開始直到最高位。

此種排序方法沒有接觸過,實現(xiàn)一遍。基數(shù)=10,建立桶,此為優(yōu)先,LSD least significant digit,次位優(yōu)先。時間復雜度,時間復雜度,T=O(P(n+b)) 桶的個數(shù)和n。 別的用途,多關鍵字的排序。時間復雜度取決于放入桶中以及收集。

堆排序

什么是堆?

不穩(wěn)定,堆排序是不穩(wěn)定的。理論上看很好,實際效果雖然是O(logn),但常數(shù)大。快速排序總是可以找到最壞的情況,平均時間復雜度為nlogn,實際中運用條件。

查找和排序

基本思路是 O(n) -> O(logn),以及要靈活利用數(shù)組本身的規(guī)律。

題目描述:LL今天心情特別好,因為他去買了一副撲克牌,發(fā)現(xiàn)里面居然有2個大王,2個小王(一副牌原本是54張_)...他隨機從中抽出了5張牌,想測測自己的手氣,看看能不能抽到順子,如果抽到的話,他決定去買體育彩票,嘿嘿!!“紅心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是順子.....LL不高興了,他想了想,決定大\小 王可以看成任何數(shù)字,并且A看作1,J為11,Q為12,K為13。上面的5張牌就可以變成“1,2,3,4,5”(大小王分別看作2和4),“So Lucky!”。LL決定去買體育彩票啦。 現(xiàn)在,要求你使用這幅牌模擬上面的過程,然后告訴我們LL的運氣如何, 如果牌能組成順子就輸出true,否則就輸出false。為了方便起見,你可以認為大小王是0。

分析: 總共五張牌,其實是一道很簡單的題,選擇排序的方式加大小王的處理即可。

題目描述:數(shù)組中有一個數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長度的一半,請找出這個數(shù)字。例如輸入一個長度為9的數(shù)組{1,2,3,2,2,2,5,4,2}。由于數(shù)字2在數(shù)組中出現(xiàn)了5次,超過數(shù)組長度的一半,因此輸出2。如果不存在則輸出0。

題目描述:輸入n個整數(shù),找出其中最小的K個數(shù)。例如輸入4,5,1,6,2,7,3,8這8個數(shù)字,則最小的4個數(shù)字是1,2,3,4,。

題目描述:輸入一個整數(shù)數(shù)組,實現(xiàn)一個函數(shù)來調(diào)整該數(shù)組中數(shù)字的順序,使得所有的奇數(shù)位于數(shù)組的前半部分,所有的偶數(shù)位于數(shù)組的后半部分,并保證奇數(shù)和奇數(shù),偶數(shù)和偶數(shù)之間的相對位置不變。

題目描述:在數(shù)組中的兩個數(shù)字,如果前面一個數(shù)字大于后面的數(shù)字,則這兩個數(shù)字組成一個逆序?qū)Α]斎胍粋€數(shù)組,求出這個數(shù)組中的逆序?qū)Φ目倲?shù)P。并將P對1000000007取模的結果輸出。 即輸出P%1000000007

鏈表類的題目

鏈表類的題目,要很好的處理好指針,不要存在內(nèi)存泄露的情況。以及還有一類快慢指針的問題。總之目前來看是很單一的題目類型。

快慢指針題

題目描述:輸入一個鏈表,輸出該鏈表中倒數(shù)第k個結點。

分析: 一個快指針先走K步,走到尾部即可。

題目進階:給一個鏈表,若其中包含環(huán),請找出該鏈表的環(huán)的入口結點,否則,輸出null。

分析

  • 是否有環(huán), 一個指針每次走兩步,一個指針每次走一步。
  • 入口節(jié)點:當快指針追上慢指針,有環(huán),此時快指針不動,計算環(huán)的大小K。
  • 讓快指針從頭先走K步,然后當兩指針相遇,為環(huán)的入口節(jié)點。

處理好指針類

題目描述:在一個排序的鏈表中,存在重復的結點,請刪除該鏈表中重復的結點,重復的結點不保留,返回鏈表頭指針。 例如,鏈表1->2->3->3->4->4->5 處理后為 1->2->5

分析:刪除重復指針的話,得一直記錄前驅(qū)節(jié)點,所以這個時候是兩個指針一起工作。注意判斷條件不要亂。

類似題: 合并兩個排序的鏈表,反轉(zhuǎn)鏈表,注意指針的處理

雙向隊列類

題目描述:給定一個數(shù)組和滑動窗口的大小,找出所有滑動窗口里數(shù)值的最大值。例如,如果輸入數(shù)組{2,3,4,2,6,2,5,1}及滑動窗口的大小3,那么一共存在6個滑動窗口,他們的最大值分別為{4,4,6,6,6,5}; 針對數(shù)組{2,3,4,2,6,2,5,1}的滑動窗口有以下6個: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

分析: 該題看了論壇上的答案,為雙向隊列處理,方法巧妙。應該記一下。

位圖

樹形數(shù)據(jù)結構

二叉樹,很多時候都要用到遞歸和動態(tài)規(guī)劃。另外樹形題目范圍很大很廣,還有很多沒有聽過的樹形結構,各有特點,先介紹一下常見的一些樹。

樹的種類和基礎知識

  • 基礎的樹形結構:二叉搜索樹,線索二叉樹,哈夫曼樹,二叉堆

  • 平衡樹: AVL,紅黑樹,2-3樹,2-3-4,B樹,B+樹,B-樹,treap SBT

  • 優(yōu)先隊列:左高樹,雙端堆,斐波那契堆

  • 集合類:并查集

  • 區(qū)間樹:線段樹,劃分樹,歸并樹

  • 字母樹:字典樹,后綴樹,AC自動向量機

  • 動態(tài)樹:伸展樹

  • 其他

    要求:時間富余時都實現(xiàn)一遍這些樹

樹的遍歷

先序和后序中序的相互變換類題目。

題目描述:重建二叉樹

分析:根據(jù)二叉樹的前序和中序/二叉樹的后序和中序重建二叉樹,關鍵點在于找準根節(jié)點。

問題:前序和后序,能重建二叉樹么?不能,前序和后序只反應出了父子關系,沒有反應出左右關系。

題目描述:輸入一個整數(shù)數(shù)組,判斷該數(shù)組是不是某二叉搜索樹的后序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數(shù)組的任意兩個數(shù)字都互不相同。

分析:二叉樹后序遍歷的題目。左子樹,右子樹,根。此樹為二叉搜索樹,則比根節(jié)點小的為左子樹,比根節(jié)點大為右子樹,遞歸即可。

題目描述:序列化二叉樹

分析:看似這題簡單,但是卻要考慮很多種形態(tài)的樹,如果不用遞歸而用循環(huán)處理和棧隊列處理的話,會出現(xiàn)很多錯。錯誤代碼可以看提交歷史,最簡潔的方法還是用遞歸。序列化選用先序遍歷,這樣可以迅速的定位根節(jié)點。用循環(huán)來處理的時候,想到了棧,但是棧在處理空葉子的時候向上回退的時候回有問題,比如是左孩子還是右孩子,誰為父親節(jié)點,總之在提交的歷史代碼里出現(xiàn)了很多錯。故解題經(jīng)驗為盡量轉(zhuǎn)換為遞歸來做。遞歸的技巧,將專門放到另一章。

題目描述:給定一棵二叉搜索樹,請找出其中的第k小的結點。例如, (5,3,7,2,4,6,8) 中,按結點數(shù)值大小順序第三小結點的值為4。

分析:遞歸?動態(tài)規(guī)劃? root_K>k,搜尋左邊,root_K = K返回, root_K<K搜尋右邊。

遍歷二叉樹/遞歸類型遍歷

題目描述:從上到下按層打印二叉樹,同一層結點從左至右輸出。每一層輸出一行。

分析: 隊列,采用雙隊列來實現(xiàn)。

題目描述:請實現(xiàn)一個函數(shù)按照之字形打印二叉樹,即第一行按照從左到右的順序打印,第二層按照從右至左的順序打印,第三行按照從左到右的順序打印,其他行以此類推。

分析: 采用雙棧來實現(xiàn),后打印的節(jié)點的孩子在下一輪先打印。

題目描述:請實現(xiàn)一個函數(shù),用來判斷一顆二叉樹是不是對稱的。注意,如果一個二叉樹同此二叉樹的鏡像是同樣的,定義其為對稱的。

分析:左子樹走一步,右子樹也要走一步。如果轉(zhuǎn)化為遞歸的話,左右子樹對稱,左右子樹的孩子也對稱。

題目描述:給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點并且返回。注意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指針。

分析: 左根右。右子樹存在,下一個,右子樹不存在,向上返回。直至返回至為父親的左孩子。

題目描述:輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)

分析: 遍歷類型題目的變種題,A得遍歷整棵樹,直至B為A的子結構。 首先找到根節(jié)點相同,然后左右子樹。還是遞歸。

題目描述:輸入一顆二叉樹的跟節(jié)點和一個整數(shù),打印出二叉樹中結點值的和為輸入整數(shù)的所有路徑。路徑定義為從樹的根結點開始往下一直到葉結點所經(jīng)過的結點形成一條路徑。(注意: 在返回值的list中,數(shù)組長度大的數(shù)組靠前)

分析:所有路徑,則該題為BFS,要遍歷所有可能的路徑。采用Queue.

題目描述:輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。

分析: 平衡二叉樹,深度差不超過1。抓準重點,左右遍歷。

題目描述:操作給定的二叉樹,將其變換為源二叉樹的鏡像。

分析:同樣也是指針的變換,將左右子樹分別交換,即為鏡像,同樣也可以為遞歸

指針變換類

題目描述:輸入一棵二叉搜索樹,將該二叉搜索樹轉(zhuǎn)換成一個排序的雙向鏈表。要求不能創(chuàng)建任何新的結點,只能調(diào)整樹中結點指針的指向。

分析: 根節(jié)點的前驅(qū)節(jié)點為左孩子的最右孩子,根節(jié)點的右邊節(jié)點為右孩子的最左孩子。可以先序遞歸,先變換自己的指針,再改變左子樹,改變右子樹。

第二次刷題的時候嘗試采用三種遍歷方式來做

遞歸和循環(huán)

能用遞歸的方法,如何用循環(huán)來實現(xiàn)??

借助stack和queue.

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容