1、為了找出倒數第k個元素,最容易想到的辦法是首先遍歷一遍單鏈表,求出整個單鏈表的長度n,然后將倒數第k個,轉換為正數第n-k個,接下來遍歷一次就可以得到結果。但是該方法存在一個問題,即需要對鏈表進行兩次遍歷,第一次遍歷用於求解單鏈表的長度,第二次遍歷用於查找正數第n-k個元素。
2、顯然,這種方法還可以進行優化。於是想到了第二種方法,如果從頭至尾的方向從鏈表中的某個元素開始,遍歷k個元素后剛好達到鏈表尾,那么該元素就是要找到的倒數第k個元素,根據這一性質,可以設計如下算法:從頭節點開始,依次對鏈表的每一個節點元素進行這樣的測試,遍歷k個元素,查看是否到達鏈表尾,只到找到哪個倒數第k個元素。此種方法將對同一批元素進行反復多次的遍歷,對於鏈表中的大部分元素而言,都要遍歷K個元素,如果鏈表長度為n個的話,該算法的時間復雜度為O(kn)級,效率太低。
3、存在另外一個更高效的方式,只需要一次遍歷即可查找到倒數第k個元素。由於單鏈表只能從頭到尾依次訪問鏈表的各個節點,因此,如果要找到鏈表的倒數第k個元素的話,也只能從頭到尾進行遍歷查找,在查找過程中,設置兩個指針,讓其中一個指針比另一個指針先前移k-1步,然后兩個指針同時往前移動。循環直到線性的指針值為NULL時,另一個指針所指向的位置就是所要找到的位置。代碼如下:
- class Node{
- Node next=null;
- int data;
- public Node(int data){
- this.data=data;
- }
- }
- public class MyLinkedList {
- Node head=null;//鏈表頭的引用
- public Node findElem(Node head,int k){
- if(k<1||k>this.length()){
- return null;
- }
- Node p1=head;
- Node p2=head;
- for(int i=0;i
參考鏈接:https://blog.csdn.net/jsqfengbao/article/details/44875779