面試 02 - 鏈表相關面試題

  1. LeetCode(Java版)19. 刪除鏈表的倒數第N個節點

解法1:不需要去遍歷兩次,一次即可,思路是,用兩個指針p,q先指向頭節點,讓q指針走到第n個位置,然後兩個指針同時往後走,走到q.next==null是說明p已經到達倒數第n個節點的前面的那個節點,此時刪除下一個節點即可。
注意:當刪除頭節點和只有一個元素的情況。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        if(head==null)
            return head; 
        ListNode p = head;
        ListNode q =head;
        //用count記錄走了多少步,和最終鏈表的長度
        int count=0;
        while(q.next!=null){
            count++;
            //前n步只讓q指針走
            if(count<=n){
                q=q.next;
            }else{
                q=q.next;
                p=p.next;
            }
        }
        //循環結束時p到達了倒數n個元素的前面一個元素
        //兩個特殊情況,即鏈表只有一個元素和要刪除的爲頭節點的情況
        if(head.next==null || count+1 == n){
            head=head.next;
        }else{
            p.next=p.next.next; 
        }
        return head;
    }
}

以下是對應的 Kotlin 版本

/**
 * Definition for singly-linked list.
 * public class ListNode {
 * int val;
 * ListNode next;
 * ListNode(int x) { val = x; }
 * }
 */
internal class Solution {
    fun removeNthFromEnd(head: ListNode?, n: Int): ListNode? {
        var head: ListNode? = head
        if (head == null) return head
        var p: ListNode = head
        var q: ListNode = head
        //用count記錄走了多少步,和最終鏈表的長度
        var count = 0
        while (q.next != null) {
            count++
            //前n步只讓q指針走
            if (count <= n) {
                q = q.next
            } else {
                q = q.next
                p = p.next
            }
        }
        //循環結束時p到達了倒數n個元素的前面一個元素
        //兩個特殊情況,即鏈表只有一個元素和要刪除的爲頭節點的情況
        if (head.next == null || count + 1 == n) {
            head = head.next
        } else {
            p.next = p.next.next
        }
        return head
    }
}

參考 https://blog.csdn.net/weixin_39043567/article/details/89813993

  1. 輸入一個鏈表,按鏈表從尾到頭的順序返回一個ArrayList。
import java.util.Stack;
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        Stack<Integer> stack = new Stack<>();
        while (listNode != null) {
            stack.push(listNode.val);
            listNode = listNode.next;
        }
        ArrayList<Integer> list = new ArrayList<>();
        while (!stack.isEmpty()) {
            list.add(stack.pop());
        }
        return list;       
    }
}
  1. 輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。
/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
       
        if(head==null)
            return null;
        //head爲當前節點,如果當前節點爲空的話,那就什麼也不做,直接返回null;
        ListNode pre = null;
        ListNode next = null;
        //當前節點是head,pre爲當前節點的前一節點,next爲當前節點的下一節點
        //需要pre和next的目的是讓當前節點從pre->head->next1->next2變成pre<-head next1->next2
        //即pre讓節點可以反轉所指方向,但反轉之後如果不用next節點保存next1節點的話,此單鏈表就此斷開了
        //所以需要用到pre和next兩個節點
        //1->2->3->4->5
        //1<-2<-3 4->5
        while(head!=null){
            //做循環,如果當前節點不爲空的話,始終執行此循環,此循環的目的就是讓當前節點從指向next到指向pre
            //如此就可以做到反轉鏈表的效果
            //先用next保存head的下一個節點的信息,保證單鏈表不會因爲失去head節點的原next節點而就此斷裂
            next = head.next;
            //保存完next,就可以讓head從指向next變成指向pre了,代碼如下
            head.next = pre;
            //head指向pre後,就繼續依次反轉下一個節點
            //讓pre,head,next依次向後移動一個節點,繼續下一次的指針反轉
            pre = head;
            head = next;
        }
        //如果head爲null的時候,pre就爲最後一個節點了,但是鏈表已經反轉完畢,pre就是反轉後鏈表的第一個節點
        //直接輸出pre就是我們想要得到的反轉後的鏈表
        return pre;
    }
}
  1. 輸入一個鏈表,輸出該鏈表中倒數第k個結點。
/*
public class ListNode {
    int val;
    ListNode next = null;
 
    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindKthToTail(ListNode list,int k) {
if (list == null)   return list;
        ListNode node = list;
        int count = 0;
        while (node != null) {
            count++;
            node = node.next;
        }
        if (count < k)  return null;
 
        ListNode p = list;
        for (int i = 0; i < count - k; i++) {
            p = p.next;
        }
        return p;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章