【优选算法】链表:两数相加,两两交换节点,重排链表,合并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;
    }
}
相关推荐
code_pgf1 小时前
Octo 算法详解-开源通用机器人策略模型技术报告
算法·机器人·开源
嘻嘻哈哈樱桃2 小时前
牛客经典101题题解集--动态规划
java·数据结构·python·算法·职场和发展·动态规划
脱氧核糖核酸__2 小时前
LeetCode热题100——234.回文链表(两种解法)
c++·算法·leetcode·链表
IronMurphy2 小时前
【算法四十二】118. 杨辉三角 198. 打家劫舍
算法
电科一班林耿超2 小时前
第 16 课:动态规划专题(二)—— 子序列与子数组问题:面试最高频的 DP 题型
数据结构·算法·动态规划
生信研究猿2 小时前
leetcode 416. 分割等和子集
算法·leetcode·职场和发展
hnjzsyjyj2 小时前
洛谷 B3622:枚举子集(递归实现指数型枚举)← DFS
数据结构·dfs
狗哥哥2 小时前
面包屑自动推导的算法设计:从“最短路径匹配”到工程可落地
算法·架构
6Hzlia3 小时前
【Hot 100 刷题计划】 LeetCode 24. 两两交换链表中的节点 | C++ 精准指针舞步
c++·leetcode·链表