从链表中移除节点

271 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

问题描述

给你一个链表的头节点 head 。

对于列表中的每个节点 node ,如果其右侧存在一个具有 严格更大 值的节点,则移除 node 。

返回修改后链表的头节点 **head **。

示例 1:

输入: head = [5,2,13,3,8]
输出: [13,8]
解释: 需要移除的节点是 5 ,2 和 3 。
- 节点 13 在节点 5 右侧。
- 节点 13 在节点 2 右侧。
- 节点 8 在节点 3 右侧。

示例 2:

输入: head = [1,1,1,1]
输出: [1,1,1,1]
解释: 每个节点的值都是 1 ,所以没有需要移除的节点。

提示:

  • 给定列表中的节点数目在范围 [1, 10^5] 内
  • 1 <= Node.val <= 10^5

思路分析

首先我们应该理解一下题目的意思,题目会给我们一个链表,对于链表中的每个节点 node ,如果其右侧存在一个具有 严格更大 值的节点,则移除 node 。这是不是就是我们之前遇到过的单调栈的思想,那么最简单的方法肯定是将链表转换成我们比较熟悉的数组来进行操作。

1、转换成数组再操作

  • 链表转换为数组

遍历整个链表,将链表中的值取出放入数组。

const list = [];
while(head){
    list.push(head.val);
    head = head.next;
}
  • 将数组转换成单调栈

每次遇到比栈顶元素大的元素时,应该先将栈顶元素出栈,直到栈内元素非严格递增

const arr = [];
for(let i = 0; i < list.length; i++){
    while(arr[arr.length - 1] < list[i]) arr.pop();
    arr.push(list[i]);
}
  • 将数组转换成链表

将得到的单调栈依次生成链表节点,最后将头结点返回即可。

let ind = 0;
const root = new ListNode(arr[ind++]);
let r = root;
while(arr.length > ind){
    r.next = new ListNode(arr[ind++]);
    r = r.next;
}
  • 完整代码
/**
 * 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 removeNodes = function(head) {
    const list = [];
    while(head){
        list.push(head.val);
        head = head.next;
    }
    const arr = [];
    for(let i = 0; i < list.length; i++){
        while(arr[arr.length - 1] < list[i]) arr.pop();
        arr.push(list[i]);
    }
    let ind = 0;
    const root = new ListNode(arr[ind++]);
    let r = root;
    while(arr.length > ind){
        r.next = new ListNode(arr[ind++]);
        r = r.next;
    }
    return root;
};

2、链表递归操作

当然我们也可以直接对链表进行递归操作来得到我们想要的结果。我们可以递归遍历链表来更新头结点,找到比头结点元素值大的节点时,我们需要更新头结点为当前节点,这样可以保证链表元素非严格递增。

node = removeNodes(head.next);
if (node.val > head.val) return node;
  • 完整代码
/**
 * 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 removeNodes = function(head) {
    if(!head.next) return head;
    node = removeNodes(head.next);
    if (node.val > head.val) return node;
    head.next = node;
    return head;
};

说在后面

本人为算法业余爱好者,平时只是随着兴趣偶尔刷刷题,如果上面分享有错误的地方,欢迎指出,感激不尽。