算法题目---链表

(一).介绍

对于做链表的题目,具体有以下技巧

1.画图。可以更直观和形象

2.引入"虚拟头节点"。这要回可以少判断很多条件,并且头插的时候更方便

3.不要吝啬空间,直接去定义

4.使用快慢双指针的思想来解决链表问题

5.链表中的常用操作

①.创建新的节点

我们直接new就可以了

②.尾插

③.头插

这时候就体现出创建虚拟头节点的作用来了

适合用于"逆序链表"

(二).具体题目

1.环形链表Ⅱ

142. 环形链表 II - 力扣(LeetCode)

解法:快慢指针

LeetCode---环形链表 II-CSDN博客

可以看这个链接

2.两数相加

2. 两数相加 - 力扣(LeetCode)

解法:模拟

java 复制代码
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode cur1=l1;
        ListNode cur2=l2;
        ListNode newHead=new ListNode(0);
        ListNode tail=newHead;
        int sum=0;
        while (cur1!=null||cur2!=null){
            if (cur1!=null){
                sum+= cur1.val;
                cur1=cur1.next;
            }
            if (cur2!=null){
                sum+= cur2.val;
                cur2=cur2.next;
            }
            tail.next=new ListNode(sum%10);
            tail=tail.next;
            sum/=10;
        }
        if (sum!=0){    //处理边界情况
            tail.next=new ListNode(sum%10);
        }
        return newHead.next;
    }

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

24. 两两交换链表中的节点 - 力扣(LeetCode)

解法:循环,迭代

4.重排链表

143. 重排链表 - 力扣(LeetCode)

解法:模拟

java 复制代码
    public void reorderList(ListNode head) {
        //先找到中间节点
        //将后面的链表进行逆置
        //重新插入链表
        ListNode fast=head;
        ListNode slow=head;
        while (fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }

        //开始进行逆置   逆置slow后面的链表
        ListNode cur=slow.next;
        slow.next=null;  //分开链表
        ListNode ret=new ListNode(0);// 使用头插法进行逆序
        while (cur!=null){
            ListNode next=cur.next;
            cur.next=ret.next;
            ret.next=cur;
            cur=next;
        }
        //进行重排序
        ListNode newHead=new ListNode(0);
        ListNode prev=newHead;
        ListNode c1=head;
        ListNode c2=ret.next;
        while (c1!=null){  //这里不需要判断c2是否为空的情况,因为前面的链表是包含slow节点的,所以前面的链表长
            prev.next=c1;
            prev=prev.next;
            c1=c1.next;
            if (c2!=null){
                prev.next=c2;
                prev=prev.next;
                c2=c2.next;
            }
        }
    }

5.合并K个升序链表

23. 合并 K 个升序链表 - 力扣(LeetCode)

解法1:模拟+优先级队列

java 复制代码
    public ListNode mergeKLists(ListNode[] lists) {
        PriorityQueue<ListNode> priorityQueue=new PriorityQueue<>(new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                return o1.val-o2.val;
            }
        });

        for (ListNode cur:lists) {
            if (cur!=null){
                priorityQueue.offer(cur);
            }
        }
        ListNode newHead=new ListNode(0);
        ListNode tail=newHead;
        while (!priorityQueue.isEmpty()){
            ListNode key=priorityQueue.peek();
            tail.next=key;
            tail=tail.next;
            priorityQueue.poll();
            if (key.next!=null){
                priorityQueue.offer(key.next);
            }
        }
        return newHead.next;
    }

解法2:使用归并排序

java 复制代码
    public ListNode mergeKLists(ListNode[] lists){
        return mergeKListsChild(lists,0,lists.length-1);
    }

    private ListNode mergeKListsChild(ListNode[] lists, int l, int r) {
        if (l>r){  //没有链表
            return null;
        }
        if (l==r){  //只有一个链表
            return lists[l];
        }

        //平分数组
        int mid=(l+r)/2;
        ListNode listNode1=mergeKListsChild(lists,l,mid);
        ListNode listNode2=mergeKListsChild(lists,mid+1,r);

        //合并两个有序链表
        return merge(listNode1,listNode2);

    }

    private ListNode merge(ListNode listNode1, ListNode listNode2) {
        if (listNode1==null){
            return listNode2;
        }
        if (listNode2==null){
            return listNode1;
        }
        ListNode cur1=listNode1;
        ListNode cur2=listNode2;

        ListNode ret=new ListNode(0);
        ListNode cur=ret;
        while (cur1!=null&&cur2!=null){
            if (cur1.val<cur2.val){
                cur.next=cur1;
                cur1=cur1.next;
            }else{
                cur.next=cur2;
                cur2=cur2.next;
            }
            cur=cur.next;
        }
        if (cur1!=null){
            cur.next=cur1;
        }
        if (cur2!=null){
            cur.next=cur2;
        }
        return ret.next;
    }

6.K个一组翻转链表

25. K 个一组翻转链表 - 力扣(LeetCode)

解法:模拟

java 复制代码
    public ListNode reverseKGroup(ListNode head, int k) {
        int n=0;
        ListNode cur=head;
        while (cur!=null){
            n++;
            cur=cur.next;
        }
        int count=n/k;
        ListNode newHead=new ListNode(0);
        ListNode prev=newHead;
        cur=head;
        for (int i = 0; i < count; i++) {
            ListNode temp=cur;
            for (int j = 0; j < k; j++) {
                ListNode next=cur.next;
                cur.next=prev.next;
                prev.next=cur;
                cur=next;
            }
            prev=temp;
        }
        prev.next=cur;
        return newHead.next;
    }
相关推荐
Snasph5 小时前
GNU Make 用户手册(中文版)
服务器·算法·gnu
江澎涌5 小时前
拆解与 AI 的一次对话
人工智能·算法·程序员
sheeta19986 小时前
LeetCode 每日一题笔记 日期:2026.06.02 题目:3635. 最早完成陆地和水上游乐设施的时间 II
笔记·算法·leetcode
Lsk_Smion6 小时前
力扣实训 _ [102].层序遍历--前序--后续_递归与非递归的实现
数据结构·算法·leetcode
Lsk_Smion7 小时前
力扣实训 _ [25].K个一组链表
数据结构·链表
小欣加油8 小时前
leetcode3751 范围内总波动值I
java·数据结构·c++·算法·leetcode
Halo_tjn8 小时前
反射与设计模式1
java·开发语言·算法
V搜xhliang02469 小时前
临床科研新范式:从选题到投稿,AI智能体如何接管全流程?
运维·数据结构·人工智能·算法·microsoft·数据挖掘·自动化
计算机安禾10 小时前
【算法分析与设计】第46篇:近似难度与不可近似性理论
网络协议·算法·ssl
小bo波10 小时前
Java Swing 可视化素数筛:动态演示 1~120 质数筛选【附完整源码】
java·算法·可视化·swing·素数