【优选算法】链表:两数相加,两两交换节点,重排链表,合并K个升序链表,K个一组反转链表

文章目录

常用技巧与操作

技巧

  1. 多画图!!直观且形象,便于理解指向关系。
  2. 引入虚拟头结点,可以使代码统一,便于处理边界情况,也方便对链表操作
  3. 大胆创建局部变量。
    举个例子:在双向链表中插入新节点,需要写四行代码,并且顺序不能随便改,要保证链表不断开,思路很复杂。而引入了局部变量就价低了思考成本,避免链表断开的问题。

    4. 快慢双指针 是非常经典的解法,可以解决判断是否有环、找环入口、俩链表中倒数第N个节点等问题

操作

  1. 创建新节点new ListNode()
  2. 尾插: 创建尾指针tail维护链表最后一个节点,tail.next = node tail = node
  3. 头插: newhead.next = head.next head = newhead方便进行逆序链表操作

1. 两数相加(LC2)

两数相加

题目描述

解题思路

直接模拟两数相加过程

  1. 创建虚拟头结点head
  2. cur1cur2分别遍历两个链表,t保存cur1cur2指向数的和,结果链表中尾插t的末位
  3. 如果上一次产生了进位,剔除t的末位,此时剩余的1表示进位,t继续+= cur1 cur2指向的数.

代码解析

java 复制代码
class Solution {
    ListNode head = new ListNode();
    ListNode tail = head;

    //尾插
    private void addLast(int val){
        ListNode node = new ListNode(val);
        tail.next = node;
        tail = node;
    }

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode cur1 = l1;
        ListNode cur2 = l2;
        int t = 0;
        while(cur1 != null && cur2 != null){
            t += cur1.val + cur2.val;
            addLast(t%10);
            t /= 10;
            cur1 = cur1.next;
            cur2 = cur2.next;
        }

        while(cur1 != null){
            t += cur1.val;
            addLast(t%10);
            t/=10;
            cur1 = cur1.next;
        }

        while(cur2 != null){
            t += cur2.val;
            addLast(t%10);
            t/=10;
            cur2 = cur2.next;
        }
        if(t==1)
            addLast(1);

        return head.next;
    }
}

注意: 如果最后t还为1,说明还有进位,要在结尾加上新节点,值为1.

拓展:链表相加二(NC40)

链表相加二

相加前需要把两个链表进行逆序操作,得到的结果也要逆序后返回。

java 复制代码
public class Solution { 
    //逆序
    private ListNode reverse(ListNode node){
        ListNode head = new ListNode(0);
        ListNode cur = node;
        while(cur!=null){
            ListNode newNode = new ListNode(cur.val);
            newNode.next = head.next;
            head.next = newNode;
            cur = cur.next;
        }
        return head.next;
    }
    
    public ListNode addInList (ListNode head1, ListNode head2) {
        // write code here
        ListNode cur1  = reverse(head1);
        ListNode cur2  = reverse(head2);

        ListNode head = new ListNode(0);
        ListNode tail = head;
        int t = 0;
        while(cur1 != null || cur2 != null || t!=0){
            if(cur1 != null){
                t += cur1.val;
                cur1 = cur1.next;
            }
            if(cur2 != null){
                t += cur2.val;
                cur2 = cur2.next;
            }
            tail.next = new ListNode(t%10);
            tail = tail.next;
            t /= 10;
        }
        head = reverse(head.next);
        return head;
    }
}
相关推荐
劈星斩月5 分钟前
监督学习算法 之 决策树
学习·算法·决策树
学计算机的计算基9 分钟前
操作系统内存管理全解:虚拟内存、页表、COW、malloc、OOM一篇搞定
java·笔记·算法
tachibana214 分钟前
hot100 前 K 个高频元素(347)
java·数据结构·算法·leetcode
To_OC8 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
旖-旎9 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
To_OC10 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
delishcomcn11 小时前
AI视觉识别+分切算法:电化铝缺陷检测与裁切一体化解锁
人工智能·算法
触底反弹11 小时前
深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战
人工智能·算法·面试
雪碧聊技术11 小时前
力扣 LCR 091. 粉刷房子 —— 动态规划入门详解
算法·动态规划