1.輸入一個鏈表,輸出該鏈表中倒數第k個結點。
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
最簡單粗暴一點的方法:先遍歷一次,得到鏈表長度l,再遍歷一次,遍歷到l-k+1處的節點即爲所求
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
int length = 1;
ListNode node = head;
if(head == null)
return null;
while(node.next != null){
length ++;
node = node.next;
}
if(k > length || k <= 0)
return null;
int count = 1;
node = head;
while(node.next != null){
if(count == length - k + 1)
return node;
else{
node = node.next;
count++;
}
}
return node;
}
}
比較聰明一點的算法是使用兩個指針,先將第一個指針移動k-1步,然後兩個指針同時移動,當第一個指針移動到鏈表結尾時,第二個指針的位置就是倒數第k個節點。如此只需遍歷一遍。
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
ListNode p1 = head;
ListNode p2 = head;
if(head == null || k <= 0)
return null;
for(int i = 1; i < k; i++){
p1 = p1.next;
if(p1 == null)
return null;
}
while(p1.next != null){
p1 = p1.next;
p2 = p2.next;
}
return p2;
}
}
2. 輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。
改變指針指向,向後改爲向前即可,無需新建鏈表,節省空間。
public class Solution {
public ListNode ReverseList(ListNode head) {
ListNode current = head;
ListNode pre = null;
ListNode next = null;
while(current != null){
next = current.next;
current.next = pre;
pre = current;
current = next;
}
return pre;
}
}
3. 輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。
參考歸併排序算法,比較兩個鏈表節點值大小,將小的插入新鏈表中,並將鏈表向後移動一位。當有某一個鏈表達到結尾時,將另一個鏈表剩下的一次性全部插入新鏈表中。
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1 == null)
return list2;
if(list2 == null)
return list1;
ListNode mergeHead = null;
ListNode current = null;
while(list1!=null && list2!=null){
if(list1.val <= list2.val){
if(mergeHead == null){
mergeHead = current = list1;
list1 = list1.next;
}else{
current.next = list1;
current = current.next;
list1 = list1.next;
}
}else{
if(mergeHead == null){
mergeHead = current = list2;
list2 = list2.next;
}else{
current.next = list2;
current = current.next;
list2 = list2.next;
}
}
}
if(list1 == null){
current.next = list2;
}else{
current.next = list1;
}
return mergeHead;
}
}