前端链表算法

1. 删除链表中的节点

前端链表算法_第1张图片

示例1

输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:指定链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9

示例2

输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:指定链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9

提示

  • 链表中节点的数目范围是 [2, 1000]
  • 1000 <= Node.val <= 1000
  • 链表中每个节点的值都是 唯一 的
  • 需要删除的节点 node 是 链表中的节点 ,且 不是末尾节点

解答

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} node
 * @return {void} Do not return anything, modify node in-place instead.
 */
var deleteNode = function(node) {
	node.val=node.next.val; //下一个节点的值赋给要删除的节点
	node=node.next.next; // 当前节点指向下下个节点
};

理解

只能找到当前节点的下一个节点,把要删除的节点的下一个节点赋值给要删除的节点,要删除的节点指向下下个节点,即删除下一个节点

2. 删除链表的倒数第N个节点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例1

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例2

输入:head = [1], n = 1
输出:[]

示例3

输入:head = [1,2], n = 1
输出:[1]

提示

  • 链表中结点的数目为 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

解答

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
 var removeNthFromEnd = function(head, n) {
 	let pre = head;
 	let lastLen=length(head)-n;
 	if(lastLen==0) return head.next; //如果lastLen==0表示删除的节点是头节点
 	for(let i=0;i<lastLen-1;i++){ //找到删除节点的前一个节点
 		pre=pre.next
 	}
 	pre.next=pre.next.next; // 然后让前一个节点的next指向要删除的节点的next
 	return head;
 }
 var length = function(head){
 	let len=0;
 	while(head!=null){
 		len++;
 		head=head.next;
 	}
 	return len;
 }

3. 反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
示例1

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例2

输入:head = [1,2]
输出:[2,1]

示例3

输入:head = []
输出:[]

提示

  • 链表中节点的数目范围是 [0, 5000]
  • 5000 <= Node.val <= 5000

解答

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var reverseList = function(head) {
	let newHead = null; //定义一个新链表
	while(head!=null){
		let temp = head.next; // 把访问节点的下一个节点先保存
		head.next=newHead; //每次访问的原链表节点都会成为新链表的头结点,其实就是把新链表挂到访问的原链表节点的后面就行了
		newHead = head;
		head = temp;
	}
	return newHead;
}

4. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例1

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例2

输入:l1 = [], l2 = []
输出:[]

示例3

输入:l1 = [], l2 = [0]
输出:[0]

提示

  • 两个链表的节点数目范围是 [0, 50]
  • 100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

解答

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} list1
 * @param {ListNode} list2
 * @return {ListNode}
 */
var mergeTwoLists = function(list1, list2) {
	//只要一个为空就返回另一个
	if(!list1||!list2){
		return list1?list1:list2
	}
	//把小的赋值给first
	let first = (list1.val<list2.val)?list1:list2;
	first.next = mergeTwoLists(first.next, newList==list1?list2:list1);
	return first
}

5. 回文链表

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例1

输入:head = [1,2,2,1]
输出:true

示例2

输入:head = [1,2]
输出:false

提示

  • 链表中节点数目在范围[1, 105] 内
  • 0 <= Node.val <= 9

解答

/* Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {boolean}
 */
var isPalindrome = function(head) {
	let fast=head,slow=head;
	//通过宽慢指针找到中点
	while(fast!=null&&fast.next!=null){
		fast=fast.next.next;
		slow=slow.next;
	};
	//fast为null是奇数
	if(fast!=null){
		slow=slow.next;
	};
	反转后半部分链表
	slow=reverseList(slow);
	fast=head;
	while(slow!=null){
		//然后比较,判断节点值是否相等
		if(slow.val!=fast.val) return false;
		fast=fast.next;
		slow=slow.next;
	}
	return true;
}
//反转
var reverseList = function(head) {
	let newHead=null;
	while(head!=null){
		let temp = head.next;
		head.next=newHead;
		newHead = head;
		head=next;
	}
	return newHead;
}

6. 环形链表

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
示例1

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例2

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例3

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

提示

  • 链表中节点的数目范围是 [0, 104]
  • 105 <= Node.val <= 105
  • pos 为 -1 或者链表中的一个 有效索引 。

解答

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */

/**
 * @param {ListNode} head
 * @return {boolean}
 */
var hasCycle = function(head) {
	if(head==null)return false;
	let slow = head,fast=head;
	while(fast!=null&&fast.next!=null){
        fast=fast.next.next;
        slow=slow.next;
        if(fast==slow) return true;
    }
    return false;
}

你可能感兴趣的:(前端,算法,链表,算法,链表)