Bootstrap

算法每日一练 (4)

💢欢迎来到张胤尘的技术站
💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥

官方站点: 力扣 Leetcode

算法每日一练 (4)

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

题目地址:删除链表的倒数第 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

进阶: 你能尝试使用一趟扫描实现吗?

解题思路

  • 首先处理边界条件,由题意可知被删除节点的次序值是小于或等于链表节点总数,并且大于等于1的,那么一定当整个链表只有一个节点时,被删除的节点次序值一定是1,故结果值一定是空(nilnullptr 或者 NULL)。
  • 另外由进阶要求得知仅仅使用一趟遍历完成题目,因为需要保证链表中节点的相对顺序,而且只能通过指针移动删除指定节点(因为只能一次遍历),因为数组(动态数组)本身根据链表的遍历后存储是有序的,而且可以通过下标直接操作链表节点,那么可以直接选择数组作为辅助。
  • 创建辅助数组(动态数组),同时也需要创建一个整形变量用于计算链表中的节点总数,后续可以直接通过总数值和待删除元素的次序值计算后得出待删除元素在数组(动态数组)的下标值。如下图所示:
    在这里插入图片描述
  • 通过临时指针变量 t 循环的将链表中的节点添加到数组(动态数组)中,并同时在循环中计算链表中节点总数。
  • 紧接着,只剩下两种情况需要判断:
    • 如果待删除的节点的次序值和节点的总数值相等,那么待删除节点就是头节点,直接将头节点指针 head 指向数组中第二个节点即可,不需要再进行下标计算。
    • 另外一种情况就是非头节点,那么需要根据上述公式计算出待删除节点在数组中的下标值后,将(下标值 - 1)的下个节点指向(下标值)的下个节点即可(进行指针移动删除中间元素)。
  • 最后返回 head 头指针即可。

解题代码

c/c++
#include <vector>

struct ListNode
{
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution
{
public:
    ListNode *removeNthFromEnd(ListNode *head, int n)
    {
        if (!head->next)
            return nullptr;

        std::vector<ListNode *> vec;
        int cnt = 0;
        ListNode *t = head;

        while (t)
        {
            vec.push_back(t);
            t = t->next;
            ++cnt;
        }

        if (n == cnt)
            head = vec[1];
        else
        {
            int target = cnt - n;
            vec[target - 1]->next = vec[target]->next;
        }

        return head;
    }
};
golang
type ListNode struct {
	Val  int
	Next *ListNode
}

func removeNthFromEnd(head *ListNode, n int) *ListNode {
	if head.Next == nil {
		return nil
	}

	slice := make([]*ListNode, 0)
	count := 0
	t := head

	for t != nil {
		slice = append(slice, t)
		t = t.Next
		count++
	}

	if n == count {
		head = slice[1]
	} else {
		target := count - n
		slice[target-1].Next = slice[target].Next
	}

	return head
}
lua
local ListNode = {}

function ListNode:new(val, next)
    local obj = {}
    setmetatable(obj, self)
    self.__index = self
    obj.Val = val or 0
    obj.Next = next or nil
    return obj
end

local function removeNthFromEnd(head, n)
    if head.Next == nil then
        return nil
    end

    local arr = {}
    local count = 0
    local t = head

    while t ~= nil do
        table.insert(arr, t)
        t = t.Next
        count = count + 1
    end

    if n == count then
        head = arr[2]
    else
        local target = count - n + 1
        arr[target - 1].Next = arr[target].Next
    end

    return head
end

🌺🌺🌺撒花!

如果本文对你有帮助,就点关注或者留个👍
如果您有任何技术问题或者需要更多其他的内容,请随时向我提问。

在这里插入图片描述

;