《剑指Offer——在O时间删除链表结点,链表中倒数第k个结点》代码
Posted 穿迷彩服的鲨鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《剑指Offer——在O时间删除链表结点,链表中倒数第k个结点》代码相关的知识,希望对你有一定的参考价值。
@TOC
前言
//==================================================================
// 《剑指Offer——在O(1)时间删除链表结点,链表中倒数第k个结点》代码
// 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该
// 结点。
// ==================================================================
// 题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,
// 本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,
// 从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是
// 值为4的结点。
//==================================================================
一、示例
1.在O(1)时间删除链表结点
/*********************************************************************
/*
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
注意:此题对比原题有改动
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
*/
***********************************************************************/
2.链表中倒数第k个结点
/******************************************************************************
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
*/
*************************************************************************/
二、代码解析
1.新建.cpp文件
代码如下(示例):
//==================================================================
// 《剑指Offer——在O(1)时间删除链表结点,链表中倒数第k个结点》代码
// 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该
// 结点。
// ==================================================================
// 题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,
// 本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,
// 从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是
// 值为4的结点。
//==================================================================
#include <iostream>
using namespace std;
struct ListNode
{
int val;
ListNode* next;
};
/*
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
注意:此题对比原题有改动
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
*/
/*法一-------双指针----指向下一个删除*/
ListNode* deleteNode1(ListNode* head, int val)
{
if (head->val == val)
{
return head->next;
}
ListNode* pNode = head;
ListNode* cNode = head->next;
while (cNode != nullptr && cNode->val != val)
{
pNode = cNode;
cNode = cNode->next;
}
if (cNode != nullptr)
{
pNode->next = cNode->next;
}
return head;
}
/*法一-------双指针----下一个覆盖上一个删除*/
void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
if (!pListHead || !pToBeDeleted)
return;
// 要删除的结点不是尾结点
if (pToBeDeleted->next != nullptr)
{
ListNode* pNext = pToBeDeleted->next;
pToBeDeleted->val = pNext->val;
pToBeDeleted->next = pNext->next;
delete pNext;
pNext = nullptr;
}
// 链表只有一个结点,删除头结点(也是尾结点)
else if (*pListHead == pToBeDeleted)
{
delete pToBeDeleted;
pToBeDeleted = nullptr;
*pListHead = nullptr;
}
// 链表中有多个结点,删除尾结点
else
{
ListNode* pNode = *pListHead;
while (pNode->next != pToBeDeleted)
{
pNode = pNode->next;
}
pNode->next = nullptr;
delete pToBeDeleted;
pToBeDeleted = nullptr;
}
}
/*
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。
示例:
给定一个链表: 1->2->3->4->5, 和 k = 2.
返回链表 4->5.
*/
/*法一---------双指针*/
ListNode* getKthFromEnd1(ListNode* head, int k)
{
if (head == nullptr || k == 0)
{
return nullptr;
}
ListNode* pNode = head;
for (int i = 0; i < k - 1; ++i)
{
if (pNode->next == nullptr)
{
return nullptr;
}
else
{
pNode = pNode->next;
}
}
ListNode* tNode = head;
while (pNode->next != nullptr)
{
pNode = pNode->next;
tNode = tNode->next;
}
return tNode;
}
/*法二--------暴力*/
ListNode* getKthFromEnd2(ListNode* head, int k)
{
ListNode* pNode = head;
int len = 0;
while (head)
{
++len;
head = head->next;
}
if (k > len)
{
return nullptr;
}
for (int i = 0; i < len - k; ++i)
{
pNode = pNode->next;
}
return head;
}
int main()
{
std::cout << "Hello World!\\n";
}
三,测试
以上是关于《剑指Offer——在O时间删除链表结点,链表中倒数第k个结点》代码的主要内容,如果未能解决你的问题,请参考以下文章