【JavaScript算法】-链表合辑01

一、02两数相加

问题描述

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例1:
在这里插入图片描述
输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.
示例2:
输入:l1 = [0], l2 = [0]
输出:[0]
示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

解题思路

这个题目的解题思路还是很简单的,首先需要新建一个链表存储结果,其余按照普通的加法做计算就行,在这里设置了一个进位数来存储进位的结果,需要注意的是在链表全部遍历结束后,仍需要对进位数进行一个判断,当其大于0时,需增加一个节点记录进位。具体代码如下:

var addTwoNumbers =function(l1,l2){
	let head=null,tail=null;  //记录新链表的头节点和尾节点
	let count=0; //记录进位
	while(l1||l2){  //这里的判断条件不是&&,因为当一个链表遍历结束后,可以将其值视为0,再与另一个链表的值相加,这样可以当作一类讨论,不做其他处理,代码更简洁
	const n1=l1?l1.val:0;
	const n2=l2?l2.val:0;
	const sum=n1+n2+count;
	if(!head){
		head=tail=new ListNode(sum%10);
	}else{//尾插法新建列表
		tail.next=new ListNode(sum%10);
		tail=tail.next;
	}
	count=Math.floor(sum/10);
	if(l1){
		l1=l1.next;
	}
	if(l2){
		l2=l2.next;
	}
}
//链表全部遍历结束后检查count有无进位
if(count>0){
	tail.next=new ListNode(carry);
}
return head;
}	

二、19 删除链表的倒数第N个节点

题目描述

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。在这里插入图片描述

解题思路

这个题的解题思路也是比较常规的一个了,看到题目就知道是先找到倒数第n个节点,然后就是删除就好。这里有两个值得注意的点,第一个需要设置虚假头节点防止真正的头节点被删除,无法返回结果;第二个是在删除节点时往往需要找到其前置节点,才能删除当前节点,所以在找倒数第n个节点时,我们可以将找第n个节点转化为找第n+1个节点,这样就不需要专门记住其前置节点 了,代码更加简洁。具体代码如下:

var removeNthFromEnd = function(head, n) {
    const dummyhead=new ListNode(0);
	dummyhead.next=head;
	let pre=fast=dummyhead;
	//找到倒数n+1个节点
	while(n-->0){
		fast=fast.next;
	}
    //fast走到最后,此时pre时倒数第n个元素的前一个元素
	while(fast&&fast.next){
		pre=pre.next;
		fast=fast.next;
	}
    pre.next=pre.next.next;
	return dummyhead.next;
};

三、21 合并两个有序列表

题目描述

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。在这里插入图片描述

解题思路

简单题,解题思路也很简单,就是不断比较然后结合成新的链表就好了。

var mergeTwoLists = function(list1, list2) {
   if(list1==null&&list2==null) return null;
   let dummyhead=new ListNode(0);
   let cur=dummyhead;
   while(list1&&list2){
       if(list1.val<=list2.val){
           cur.next=list1;
           list1=list1.next;
       }else{
           cur.next=list2;
           list2=list2.next;
       }
       cur=cur.next;
   }
   while(list1){
       cur.next=list1;
       list1=list1.next;
       cur=cur.next;
   }
   while(list2){
       cur.next=list2;
       list2=list2.next;
       cur=cur.next;
   }
   return dummyhead.next;
};

三、技巧总结

  1. 对于链表问题,在返回结果为头节点时,通常需要先初始化一个预先指针pre或者说假性头节点dummyhead,该指针的下一个节点指向真正的头节点head。这是为了在链表构造或者移动过程中,防止头指针丢失,从而无法返回结果。
  2. 快慢指针找节点,这个就是模板了感觉,找第n个,倒数第n个,以及中间节点,都是相同的套路,注意快慢指针之间的间隔就好了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值