2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案

1.题目描述

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

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

2.解题报告

在对链表进行操作时,一种常用的技巧是添加一个哑节点(dummy node),它的 \textit{next}next 指针指向链表的头节点。这样一来,我们就不需要对头节点进行特殊的判断了。

例如,在本题中,如果我们要删除节点 yy,我们需要知道节点 yy 的前驱节点 xx,并将 xx 的指针指向 yy 的后继节点。但由于头节点不存在前驱节点,因此我们需要在删除头节点时进行特殊判断。但如果我们添加了哑节点,那么头节点的前驱节点就是哑节点本身,此时我们就只需要考虑通用的情况即可。

这个题目是双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。

3.最优答案

c答案


/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//定义两个指针,刚开始分别指向头结点,然后先让一个指针先走n-1步,接着两个指针同时遍历链表,当第一个指针到达链表尾部的时候,第二个指针指向的就是要删除的倒数第n个结点。
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode *fast=head;
struct ListNode *slow=head;
for(int i=0;i<n;i++){
fast=fast->next;
if(fast==NULL) return head->next;
}
while(fast->next !=NULL){
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return head;
// struct ListNode *fast=head;
// struct ListNode *slow=head;
// int i;
// for(i=0;i<n;i++)
// {
// fast=fast->next;
// if(fast == NULL) return head->next;
// }
// while(fast->next != NULL)
// {
// fast=fast->next;
// slow=slow->next;
// }
// slow->next=slow->next->next;
// return head;
}

c++答案


class Solution
{
public:
ListNode* removeNthFromEnd(ListNode* head, int n)
{
if (!head->next) return NULL;//空链表 ListNode *pre = head, *cur = head; for (int i = 0; i < n; i++)
cur = cur->next;
if (!cur)
return head->next;//cur==NULL,此时n大于链表长度,返回首元素 while (cur->next)
{
cur = cur->next;
pre = pre->next;//cur先走了n个长度,领先pre了n个长度;所以当cur走到末尾时,pre刚好指向倒数第n个节点
}
pre->next = pre->next->next;
return head;
}
};

java答案


/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode root =head;
HashMap<Integer,ListNode> map = new HashMap<>();
int count = 0; while(head != null){
count += 1;
map.put(count,head);
head = head.next;
}
if(count == 1 || count == n){
root = root.next;
}else if(n == 1 && count ==2){
map.get(count - n ).next = null;
}else {
map.get(count - n ).next = map.get(count - n + 2);
} return root;
}
}

JavaScript答案


/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
if(head == null || n <= 0) {
return head;
}
var dummy = new ListNode(0);
dummy.next = head;
var p = dummy
var q = dummy
for(var i = 0; i < n + 1; i++) {
p = p.next;
}
while(p) {
p = p.next;
q = q.next
}
q.next = q.next.next;
return dummy.next;
// var count = 0;
// var p = head;
// while(p) {
// count++
// p = p.next
// }
// //顺数第m个
// var m = count - n + 1;
// var dummy = new ListNode(0);
// dummy.next = head;
// var cur = dummy;
// for(var i = 1; i < m; i++) {
// cur = cur.next;
// }
// cur.next = cur.next.next;
// return dummy.next;
};

c#答案


/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode RemoveNthFromEnd(ListNode head, int n) {
if(head==null)return null;
var list=new List<ListNode>(){head};
int i=0;
while(i<list.Count){
if(list[i].next!=null) {
list.Add(list[i].next);
}
i++;
}
if(list.Count==1){
return null;
}
else if(list.Count==n){
return list[1];
}
i=list.Count-n;
if(i>-1){
if(n==1){
list[list.Count-2].next=null;
}
else if(i-i>=0 && i+1<list.Count)
list[i-1].next=list[i+1]; }
return list[0]; }
}

python2.x答案


# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummy = ListNode(0)
dummy.next = head
first = second = dummy
for i in range(n):
first = first.next
while first.next:
first = first.next
second = second.next
second.next = second.next.next
return dummy.next

python3.x答案


# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None class Solution:
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
head2 =[head.val]
while head.next != None:
head =head.next
head2.append(head.val)
head2.pop(-n)
return head2

go答案


/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/ func removeNthFromEnd(head *ListNode, n int) *ListNode {
var arr []*ListNode
arr = append(arr, head)
for node := head; node.Next != nil; node = node.Next {
arr = append(arr, node.Next)
} if n == len(arr) {
head = head.Next
} else if n == 1 {
del := arr[len(arr)-2]
del.Next = nil
} else {
del := arr[len(arr)-n]
deleteNode(del)
}
return head
} func deleteNode(node *ListNode) {
next := node.Next
node.Val = next.Val
node.Next = next.Next
}

4.算法面试宝典小程序

微信搜“算法面试宝典”,内含1000个算法题目的7种语言的top5答案和详细解题报告,无论是校招还是社招,让你算法面试中游刃有余,助力薪酬提升30%。

2021字节跳动校招秋招算法面试真题解题报告--leetcode19 删除链表的倒数第 n 个结点,内含7种语言答案的更多相关文章

  1. 2021字节跳动校招秋招算法面试真题解题报告--leetcode206 反转链表,内含7种语言答案

    206.反转链表 1.题目描述 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1-> ...

  2. 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II

    [算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...

  3. 【剑指Offer面试编程题】题目1517:链表中倒数第k个结点--九度OJ

    题目描述: 输入一个链表,输出该链表中倒数第k个结点. (hint: 请务必使用链表.) 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行为两个整数n和k(0< ...

  4. 打败算法 —— 删除链表的倒数第n个结点

    本文参考 出自LeetCode上的题库 -- 删除链表的倒数第n个结点,官方的双指针解法没有完全符合"只遍历一遍链表"的要求,本文给出另一种双指针解法 https://leetco ...

  5. 字节跳动Android春招,三轮面试,夺命连环问,心态崩了

    我是春招参加字节面试的,现在已经入职俩月啦,当时没有及时记录下来拖到现在...我尽量回忆当时的内容希望能帮到大家. 投的部门是深圳字节影像,不得不说这个部门的效率,上午投下午就接到hr的电话约面试时间 ...

  6. 2021年最新字节跳动Android面试真题解析

    概述 时间过得是真TM快,回想自己是16年从学校毕业,现在是出来工作的第五个年头啦.在不同的大小公司都待过,就在前段时间顺利的完成了一次跳槽涨薪,面试了几家公司,最终选择了字节跳动.今特此前来跟大家进 ...

  7. 秋招如何抱佛脚?2022最新大厂Java面试真题合集(附答案

    2022秋招眼看着就要来了,但是离谱的是,很多同学最近才想起来还有秋招这回事,所以纷纷临时抱佛脚,问我有没有什么快速磨枪的方法, 我的回答是:有! 说起来,临阵磨枪没有比背八股文更靠谱的了,很多人对这 ...

  8. 数据结构+算法面试100题~~~摘自CSDN

    数据结构+算法面试100题~~~摘自CSDN,作者July 1.把二元查找树转变成排序的双向链表(树) 题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调 ...

  9. 面试系列二:精选大数据面试真题JVM专项-附答案详细解析

    公众号(五分钟学大数据)已推出大数据面试系列文章-五分钟小面试,此系列文章将会深入研究各大厂笔面试真题,并根据笔面试题扩展相关的知识点,助力大家都能够成功入职大厂! 大数据笔面试系列文章分为两种类型: ...

随机推荐

  1. Prometheus+Grafana企业监控系统

    Prometheus+Grafana企业监控系统 作者 刘畅 实验配置: 主机名称 Ip地址 controlnode 172.16.1.70/24 slavenode1 172.16.1.71/24 ...

  2. SQL 小知识笔记

    1.自动生成序列号 select row_number() over(order by field1) as row_number,* from t_table

  3. web自动化页面元素不能键盘输入

    一.背景 web自动化中存在一部分元素属性是readonly属性,导致我们在使用自动化代码的时候无法使用sendkeys()方法传入数据,以12306网站选择出发日期为例,见下图 二.json语句处理 ...

  4. 其他:Windows10安装自带的Linux

    1.首先我们要打开Windows功能 2.在这里把勾打上 3.然后打开 设置 --- 更新和安全 --- 针对开发人员 --- (选择)开发人员模式 --- 确定启动 就行了 4.打开PowerShe ...

  5. 排序---python版

    冒泡排序: 比较相邻的元素.如果第一个比第二个大,就交换它们两个: 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数: 针对所有的元素重复以上的步骤,除了最 ...

  6. Java基础00-异常25

    1. 异常 异常 1.1 异常概述 1.2 JVM的默认处理方案 有一行代码报错,下面的代码就不会执行. 1.3 异常处理 如果程序出现了异常,需要我们自己来处理,因为在实际的开发中,不能因为一处的报 ...

  7. 单细胞分析实录(17): 非负矩阵分解(NMF)代码演示

    本次演示使用的数据来自2017年发表于Cell的头颈鳞癌单细胞文章:Single-Cell Transcriptomic Analysis of Primary and Metastatic Tumo ...

  8. 【LeetCode】523. 连续的子数组和

    523. 连续的子数组和 知识点:数组:前缀和: 题目描述 给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组: 子数组大小 至少为 2 ,且 ...

  9. Scala学习——面向对象

    Scala面向对象 三大特征:封装.继承.多态 1.类的定义和使用 package top.ruandb.scala.Course02 object Simple { def main(args: A ...

  10. 微信小程序云开发-添加数据

    一.数据的添加 使用add方法添加数据 添加完成后,在数据库中查询,可以看到数据库中添加了1条数据,此时添加的数据系统自动添加了_openid 将[添加]功能写到对应的方法中 wxml页面中,点击[添 ...