【力扣hot100】链表专题|21、2、19、24、92、25

链表专题

文章目录

  • 链表专题
      • [21. 合并两个有序链表](#21. 合并两个有序链表)
      • [2. 两数相加](#2. 两数相加)
      • [19. 删除链表的倒数第 N 个结点](#19. 删除链表的倒数第 N 个结点)
      • [24. 两两交换链表中的节点](#24. 两两交换链表中的节点)
      • 92.反转链表II
      • [25. K 个一组翻转链表](#25. K 个一组翻转链表)

21. 合并两个有序链表

21. 合并两个有序链表

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode dummy = new ListNode();
        ListNode cur = dummy; // cur 指向新链表的末尾
        while (list1 != null && list2 != null) {
            if (list1.val < list2.val) {
                cur.next = list1; // 把 list1 加到新链表中
                list1 = list1.next;
            } else { // 注:相等的情况加哪个节点都是可以的
                cur.next = list2; // 把 list2 加到新链表中
                list2 = list2.next;
            }
            cur = cur.next;
        }
        cur.next = list1 != null ? list1 : list2; // 拼接剩余链表
        return dummy.next;
    }
}

2. 两数相加

2. 两数相加

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head = null,tail = null;
        int carry = 0;
        while(l1 != null || l2 != null){
            int n1 = l1 != null ? l1.val : 0;
            int n2 = l2 != null ? l2.val : 0;
            int sum = n1 + n2 + carry;
            if(head == null){
                head = tail = new ListNode(sum % 10);
            }else{
                tail.next = new ListNode(sum % 10);
                tail = tail.next;
            }
            carry = sum / 10;
            if(l1 != null){
                l1 = l1.next;
            }
            if(l2 != null){
                l2 = l2.next;
            }
        }
        //如到最后还有进位就再增加一个节点
        if(carry > 0){
            tail.next = new ListNode(carry);
        }

        return head;
    }
}

需要注意的

"短链表要补零""最后进位别忘掉"

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

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

先计算链表长度,再循环得到要删除的前一个节点

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        int length = getLength(head);
        if(length == n)return head.next;
        ListNode curr = head;
        for(int i = 1;i < length - n;i++){
            curr = curr.next;
        }
        curr.next = curr.next.next;
        return head;
    }
    private int getLength(ListNode head){
        int length = 0;
        while(head != null){
            length++;
            head = head.next;
        }
        return length;
    }
}

要注意for(int i = 1;i < length - n;i++)的范围,以防指向null

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

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

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode tempHead = new ListNode(0,head);
        ListNode temp = tempHead;
        while(temp.next != null && temp.next.next != null){
            ListNode l = temp.next;
            ListNode r = temp.next.next;
            temp.next = r;
            l.next = r.next;
            r.next = l;

            temp = l;
        }

        return tempHead.next;//不能return head 因为head还是指向以前的头结点
    }
}

temp停在当前处理节点的前一个位,l和r分别是temp的后面第1个和后面第2个(即待处理的两位节点)

92.反转链表II

92. 反转链表 II

为了应对left=1这一特殊情况,还需要在链表前加一个哨兵节点

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode dummy = new ListNode(0,head);
        ListNode p0 = dummy;
        // 找到要反转部分的前一个
        for(int i=0;i<left-1;i++){
            p0 = p0.next;
        }
        // 反转要反转的部分
        ListNode pre = null,curr = p0.next;
        for(int i = 0;i<right-left+1;i++){
            ListNode nxt =  curr.next;
            curr.next = pre;
            pre = curr;
            curr = nxt;
        }
        p0.next.next = curr;
        p0.next = pre;

        return dummy.next;

    }
}

25. K 个一组翻转链表

25. K 个一组翻转链表

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        // 统计节点个数
        int n = 0;
        for (ListNode cur = head; cur != null; cur = cur.next) {
            n++;
        }

        ListNode dummy = new ListNode(0, head);
        ListNode p0 = dummy;
        ListNode pre = null;
        ListNode cur = head;

        // k 个一组处理
        for (; n >= k; n -= k) {
            for (int i = 0; i < k; i++) { // 同 92 题
                ListNode nxt = cur.next;
                cur.next = pre; // 每次循环只修改一个 next,方便大家理解
                pre = cur;
                cur = nxt;
            }

            // 见视频
            ListNode nxt = p0.next;
            p0.next.next = cur;
            p0.next = pre;
            p0 = nxt;
        }
        return dummy.next;
    }
}
相关推荐
一木 之林29 分钟前
五、C++ 新特性、关键字与编译原理(进阶)(二)
java·开发语言·c++
OPEN-F43 分钟前
C++11/14新特性精讲:移动语义与智能指针实战
开发语言·c++·算法
洋不写bug44 分钟前
绕过权限检查,访问修改私有属性,反射,枚举,lambda
java·枚举·lambda·反射
evans在进步1 小时前
Java 常用设计模式入门:建造者、工厂、单例、外观与代理
java·python·设计模式
lisin-lee-cooper1 小时前
【leetcode658】有序数组找出k个最接近x的数
java·数据结构·算法
sunburn-1 小时前
Java堆(Heap)详解与实战教学
java·开发语言·数据结构·ide·算法
Kyrie_kk1 小时前
Java--TimeUnit时间单位枚举类(时间单位规范)
java·后端
念何架构之路2 小时前
beego总体架构与工程结构
java·架构·beego
典典分享指南2 小时前
用飞书多维表格搭建内容管理看板
java·python·r语言·composer·symfony
智碳能碳管理平台2 小时前
工业能耗台账标准化:能碳管理系统的数据口径怎么设计
算法·能碳管理系统·智碳能碳管理平台·企业能碳管理系统·碳排放核算软件·绿色工厂申报saas·能碳管理平台