算法题目---链表

(一).介绍

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

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;
    }
相关推荐
luoganttcc2 小时前
华为昇腾(Ascend)等芯片,同样存在“寄存器 / 片上存储资源限制并发”的问题
算法·华为
小O的算法实验室2 小时前
2025年SEVC,神经-粒子群算法+大规模动态优化,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
wayz112 小时前
Day 7:第一周复习与模型综合比较
人工智能·算法·机器学习·量化交易
玛丽莲茼蒿2 小时前
Leetcode hot100 买卖股票的最佳时机【简单】
算法·leetcode·职场和发展
阿Y加油吧2 小时前
两道 LeetCode 题的复盘笔记:从「只会暴力」到「懂优化」
笔记·算法·leetcode
We་ct2 小时前
LeetCode 300. 最长递增子序列:两种解法从入门到优化
开发语言·前端·javascript·算法·leetcode·typescript
wayz113 小时前
Day 9 :随机森林调参与时间序列交叉验证
算法·随机森林·机器学习
️是783 小时前
信息奥赛一本通—编程启蒙(3371:【例64.2】 生日相同)
开发语言·c++·算法
ZPC82103 小时前
ROS2 快过UDP的方法
python·算法·机器人