劍指offer--關於連結串列操作的演算法
阿新 • • 發佈:2018-11-13
題1:輸入一個連結串列,輸出該連結串列中倒數第k個結點。
思路1:
因為我們拿到的是第一個結點,不知道最後一個結點在哪。但是我們可以發現,從第一個結點走到倒數第K個結點的長度和正著第k個結點到最後一個結點的長度一樣。所以我們可以用兩個指標指向第一個結點,讓第一個指證先走k-1步,然後兩個指證一起走,這樣,第一個指標走到底的時候,第二個指標也走到了倒數第k個結點。
思路2:直接用一個count計數,進入while迴圈,只要head.next不為空,count++。這樣就直接得出連結串列的長度。然後從head結點走count-k步就到達倒數第k個位置。
程式碼:
public ListNode FindKthToTail(ListNode head,int k) { if(head==null||k<=0){ return null; } ListNode pre=head; ListNode last=head; for(int i=1;i<k;i++){ if(pre.next!=null){ pre=pre.next; }else{ return null; } } while(pre.next!=null){ pre = pre.next; last=last.next; } return last; }
題2:輸入一個連結串列,反轉連結串列後,輸出連結串列的所有元素。
思路:反轉連結串列,那麼第一步head結點將指向一個空結點Pre,那為了保證head後面的連結串列不會斷掉,第二步要用一個結點來代替原來的head,假設為last,第三步last.next在指向原來的head結點。第四步,pre指向head,head指向last,依次後移,將連結串列反轉。
程式碼:
public ListNode ReverseList(ListNode head) { ListNode pre=null; ListNode next=null; if(head==null) return null; while(head!=null) {
next=head.next;
head.next=pre;
pre=head;
head=next;
}
return pre;
}
題3:輸入兩個單調遞增的連結串列,輸出兩個連結串列合成後的連結串列,當然我們需要合成後的連結串列滿足單調不減規則。
思路:使用遞迴,我們可以看一個例子 { 1,3,5 }{2,4,6}第一個連結串列中的第一個數字和
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1 == null){
return list2;//如果list1為空了,返回list2。
}
if(list2 == null){
return list1;//如果list2為空,返回List1
}
if(list1.val <= list2.val){//如果List1的值小於list2的值
list1.next = Merge(list1.next, list2);//比較list1.next和list2的大小,複製給next。
return list1;//返回List1.
}else{
list2.next = Merge(list1, list2.next);//如果大於,返回List2為開始結點,繼續比較List2,next和list1的大小
return list2;
}
}