数据结构刷题(五):24两两交换链表中的节点、19 删除链表的倒数第 N 个结点、160链表相交

1.两两交换链表中的节点

题目链接

思路:虚拟头结点 递归

注意:对于需要交换的两个节点,可以直接使用firstnode和secondnode进行保存

解法一(虚拟头结点):

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(-1,head);
        ListNode cur = head;
        ListNode temp = null;
        ListNode pre = dummy;
        // while这么写理由: 保证每次交换都能做到两两交换
        while (pre.next != null && pre.next.next != null){
            temp = cur.next.next;
            pre.next = cur.next;
            cur.next.next = cur;
            cur.next = temp;
        // 注意以下pre和cur的顺序
            pre = cur;
            cur = cur.next;
        }
        return dummy.next;
    }
}

解法二(递归):

class Solution {
    public ListNode swapPairs(ListNode head) {
        // base case 退出提交
        if(head == null || head.next == null) return head;
        // 获取当前节点的下一个节点
        ListNode next = head.next;
        // 进行递归
        ListNode newNode = swapPairs(next.next);
        // 这里进行交换
        next.next = head;
        head.next = newNode;
        return next;
    }
} 

2.删除链表的倒数第 N 个结点

题目链接

思路:链表的快慢指针

注意:链表head的大小不知,设置快指针先走n步,然后快慢一起走,直到快指针走到最后,也就得到了倒数第N个结点。

解法:

public ListNode deleteIndex( ListNode head,int n) {

    // 得不到链表的size
    ListNode dummyNode = new ListNode(0);
    dummyNode.next = head;

    ListNode fast = dummyNode;
    ListNode slow = dummyNode;
    for (int i = 0; i < n; i++) {
        fast = fast.next;
    }
    while (fast.next != null) {
        fast = fast.next;
        slow = slow.next;
    }

    slow.next = slow.next.next;
    return dummyNode.next;
}

3.链表相交

题目链接

思路:就是求两个链表交点节点的指针,用curA指向链表A的头结点,curB指向链表B的头结点

注意:这里直接假设节点元素数值相等,则节点指针相等。(很多版本都解释不通)

解法:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    ListNode curA = headA;
    ListNode curB = headB;
    int lenA = 0, lenB = 0;
    while (curA != null) { // 求链表A的长度
        lenA++;
        curA = curA.next;
    }
    while (curB != null) { // 求链表B的长度
        lenB++;
        curB = curB.next;
    }
    curA = headA;
    curB = headB;
    // 让curA为最长链表的头,lenA为其长度
    if (lenB > lenA) {
        //1. swap (lenA, lenB);
        int tmpLen = lenA;
        lenA = lenB;
        lenB = tmpLen;
        //2. swap (curA, curB);
        ListNode tmpNode = curA;
        curA = curB;
        curB = tmpNode;
    }
    // 求长度差
    int gap = lenA - lenB;
    // 让curA和curB在同一起点上(末尾位置对齐)
    while (gap-- > 0) {
        curA = curA.next;
    }
    // 遍历curA 和 curB,遇到相同则直接返回
    while (curA != null) {
        if (curA == curB) {
            return curA;
        }
        curA = curA.next;
        curB = curB.next;
    }
    return null; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值