Day4 链表|| 两两交换 删除指定节点 链表相交 环形链表

24 两两交换链表中的节点

题目链接:24.两两交换链表中的节点

思路:拿到题目,对题目中“不修改节点内部值”这个要求不太理解怎么做。想到了就是设置虚拟头节点,依次向后两两交换顺序!!直到看到了讲解中设置的 firstnode 和 secondnode 才理解一些不修改内部值这个要求以及如何实现。

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode fake = new ListNode(-1, head);
        ListNode cur = fake;
        ListNode temp;
        ListNode firstnode;
        ListNode secondnode;
        while(cur.next != null && cur.next.next != null){;
        temp = cur.next.next.next;
        firstnode = cur.next;
        secondnode = cur.next.next;
        cur.next = secondnode;
        cur.next.next = firstnode;
        firstnode.next = temp;
        cur = firstnode;
        }
    return fake.next;
    }
   
}

递归版本还每太完全看懂!!!!

19.删除链表的倒数第N个节点

题目链接:19.删除链表的倒数第N个节点

思路:拿到题目,先想到暴力解法:先扫描一遍得出链表长度,再得出需要删除的节点位置,扫描第二次到指定位置 删除节点。然后想到了双指针方法,扫描一遍,即可找到所需删除元素。

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode fake = new ListNode(-1,head);
        ListNode fast = fake;
        ListNode slow = fake;
        for(int i = 0; i <= n; i++){
            fast = fast.next;
        }

        while(fast != null){
            slow = slow.next;
            fast = fast.next;
        }

        slow.next = slow.next.next;
        return fake.next;


    }
}

注意点:

1、首先注意这里 fast 和 slow指针中间的间隔应该设置为多少!

2、什么时候停止—— 经常混淆fast  != null 及 fast.next != null。

02.07 链表相交

题目链接: 02.07 链表相交

思路:拿到这道题,想的是暴力解法,一个指针在A链表,一个指针在B链表;B链表中的指针先固定不动,遍历A指针,若有相同,则返回;没有相同则B链表指针向后移一位,再对A链表进行遍历操作。以此类推!但是这个方法时间复杂度太高了。

方法:看讲解后,实际上是对齐链表尾部,从短链表初始位置一起开始移动,相互比较,找出相同的节点。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode curA = headA;
        ListNode curB = headB;
        int countA = 1;
        int countB = 1;
        while(curA != null){
            curA = curA.next;
            countA ++;
        }
        while(curB != null){
            curB = curB.next;
            countB ++;
        }
        int n = countB - countA;
        curA = headA;
        curB = headB;
        if(n >= 0){
            for(int i = 0; i < n;i++){
                curB = curB.next;
            }
            }else{
                for(int i = 0; i < -n; i++){
                    curA = curA.next;
                }
        }

        while(curA != null && curB != null){
            if(curA == curB){
                return curA;
            } 
            curA = curA.next;
            curB = curB.next;
            
        }
        return null;
        

        
    }
}

142.环形链表 Ⅱ

题目链接:142. 环形链表 II

方法:

1、判断有无环的方法:设定快慢指针,快指针每次走两个节点,慢指针每次走一个节点,若两个指针能相遇,则说明链表有环!!!

2、如何找到链表环入口:一个指针从头节点出发,一个指针从相遇节点出发,两指针再次相遇地点即为链表环入口节点!!

这道题,主要学会如何判断链表环,以及思考如何找到链表环的推理过程。

public class Solution {
    public ListNode detectCycle(ListNode head) {
           ListNode slow = head;
           ListNode fast = head;
           while(fast != null && fast.next != null){
                 slow = slow.next;
                 fast = fast.next.next;
                 if(fast == slow){
                    ListNode index1 = head;
                    ListNode index2 = fast;
                    while(index1 != index2){
                          index1 = index1.next;
                          index2 = index2.next;
                    }
                    return index1;
                    
                  }
           }
           return null;
           
    }
}

注意点:

1、注意判定是否有环的代码while里面的判定条件 要看fast和fast.next是否为空 因为最小的环就是fast.next = fast,这种情况。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是递归实现两两交换链表中的节点的C语言代码: ```c #include <stdio.h> #include <stdlib.h> struct ListNode { int val; struct ListNode *next; }; struct ListNode* swapPairs(struct ListNode* head) { if (head == NULL || head->next == NULL) { return head; } struct ListNode *newHead = head->next; head->next = swapPairs(newHead->next); newHead->next = head; return newHead; } int main() { struct ListNode *node1 = (struct ListNode*)malloc(sizeof(struct ListNode)); struct ListNode *node2 = (struct ListNode*)malloc(sizeof(struct ListNode)); struct ListNode *node3 = (struct ListNode*)malloc(sizeof(struct ListNode)); struct ListNode *node4 = (struct ListNode*)malloc(sizeof(struct ListNode)); node1->val = 1; node2->val = 2; node3->val = 3; node4->val = 4; node1->next = node2; node2->next = node3; node3->next = node4; node4->next = NULL; struct ListNode *newHead = swapPairs(node1); while (newHead != NULL) { printf("%d ", newHead->val); newHead = newHead->next; } return 0; } ``` 以上代码中,我们定义了一个结构体 `ListNode` 表示链表节点,包含一个整型变量 `val` 和一个指向下一个节点的指针 `next`。函数 `swapPairs` 是递归实现两两交换链表中的节点的函数,它的参数是链表节点指针 `head`,返回值是交换后的链表节点指针。如果链表为空或者只有一个节点,直接返回该节点;否则,交换前两个节点,并递归处理剩下的节点。最后返回新的链表节点指针。 在 `main` 函数中,我们创建了一个包含四个节点链表,并调用 `swapPairs` 函数对链表进行两两交换。最后输出交换后的链表节点值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值