一些典型的链表面试题!试一试你能否解答..(包含详细解答即注意事项)

 1.反转链表

        链接:206. 反转链表 - 力扣(LeetCode)

        详细解答:

class Solution {
    public ListNode reverseList(ListNode head) {
        //当只有一个节点或头节点为空时,直接返回这个节点
        if(head == null || head.next == null) {
            return head;
        }

        ListNode cur = head.next;
        head.next = null;//原链表头节点在反转后会变成尾节点,next为null

        while(cur != null) {
           //在头插之前,定义curNext记录在翻转的节点后一个节点的地址;若不记录curNext节点,就会陷入死循环.
            ListNode curNext = cur.next;
            cur.next = head;
            head = cur;
            cur = curNext;
        }
        return head; 
    }
}

2.链表的中间节点

链接:876. 链表的中间结点 - 力扣(LeetCode)

 重点:快慢指针,当fast走两步,slow走一步,这时slow走的路程是fast的一半;结合到链表中当fast停下,slow所在的节点就是要找的中间节点!

        注意事项:fast在偶数节点和奇数节点所结束的停下是不一样的!

class Solution {

    public ListNode middleNode(ListNode head) {

        ListNode fast = head;

        ListNode slow = head;

      //fast != null 是偶数链表时fast停下的条件

      //fast.next != null 是奇数链表时fast停下的条件

        while(fast != null && fast.next != null) {

            fast = fast.next.next;

            slow = slow.next;

        }

        return slow;

    }

}

3.获取链表倒数第k个节点

链接:链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com)

注:快慢指针!

public class Solution {
    public ListNode FindKthToTail(ListNode head,int k) {
        // fast先往后走k步
        ListNode fast = head;
        while(0 != k--){
            // 如果fast为空,说明k大于链表中节点个数
            if(null == fast){
                return null;
            }
            fast = fast.next;
        }        
        // 然后fast和slow同时往后移动,
        // 当fast走到末尾的时候,slow刚好是倒数第k个节点
        ListNode slow = head;
        while(null != fast){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}

4.合并两个有序链表

链接:21. 合并两个有序链表 - 力扣(LeetCode) 

注:newHead就相当于一个傀儡节点

/*
    解题思路:
      1. 如果两个链表中有一个为空,则返回另外一个
      2. 遍历两个链表,将较小的节点往新链表中尾插,注意:为了实现方便,新链表使用带头节点的链表
      3. 循环结束之后,肯定有一个链表先走到末尾,将另外一个不空的链表直接连接在tail之后
*/    
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        // 如果两个链表中有一个为空,则返回另外一个
        if(null == list1){
            return list2;
        }
        if(null == list2){
            return list1;
        }
        // 遍历两个链表,将较小的节点往新链表中尾插
        // 为了实现方便,新链表使用带头节点的链表
        ListNode newHead = new ListNode();
        ListNode tail = newHead;
        ListNode cur1 = list1;
        ListNode cur2 = list2;
        // 只要两个链表都不为空,从前往后遍历
        // 将小的尾插到tail之后
        while(null != cur1 && null != cur2){
            if(cur1.val <= cur2.val){
                tail.next = cur1;
                cur1 = cur1.next;
            }else{
                tail.next = cur2;
                cur2 = cur2.next;
            }
            tail = tail.next;
        }
        // while结束之后,肯定有一个链表先走到末尾
        // 将另外一个不空的链表直接连接在tail之后
        if(null != cur1){
            tail.next = cur1;
        }else{
            tail.next = cur2;
        }
        return newHead.next;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值