题目15 链表中倒数第K个节点
/////////////////////////////////////////////////////////////////////////////////////
// 5. 题目15 链表中倒数第K个节点
//时间复杂度:O(n),空间复杂度O(n)
ListNode<int>* KthNodeFromEnd(ListNode<int>* pNode, int k)
{
if (pNode == NULL || k <= 0)
{
return NULL;
} ListNode<int>* p = pNode;
stack<ListNode<int>*> stStack; // 把链表数据全部压入栈
while (p)
{
stStack.push(p);
p = p->m_pNextNode;
} // 检查K的合法性
if (k > (int)stStack.size())
{
return NULL;
} while (!stStack.empty() && --k > 0)
{
stStack.pop();
} return stStack.top();
} // 方法二:倒序第K个元素 --> 正序(N - K)
//时间复杂度:O(n), 空间复杂度O(1) --> 需要遍历两次链表
ListNode<int>* KthNodeFromEnd_2(ListNode<int>* pNode, int k)
{
if (NULL == pNode || k <= 0)
{
return NULL;
} ListNode<int>* p = pNode;
int iNodeCount = 0; while (p)
{
iNodeCount++;
p = p->m_pNextNode;
} int iLoopCount = iNodeCount - k;
if (iLoopCount < 0)
{
return NULL;
} while (pNode && iLoopCount-- > 0)
{
pNode = pNode->m_pNextNode;
} return pNode;
} //方法三: 定义两个指针,两个指针之间相差(K-1),第一个指针遍历完,第二个指针指向的就是需要的节点
//时间复杂度:O(n),空间复杂度 : O(1) --> 只遍历一遍链表
ListNode<int>* KthNodeFromEnd_3(ListNode<int>* pNode, int k)
{
if (pNode == NULL || k <= 0)
{
return NULL;
} ListNode<int>* p1 = pNode;
ListNode<int>* p2 = pNode; while (p1 && p1)
{
if (--k < 0)
{
p2 = p2->m_pNextNode;
} p1 = p1->m_pNextNode;
} // K 超出了链表个数
if (k > 0 && p1 == NULL)
{
return NULL;
} return p2;
} // 扩展一:
// 求链表的中间节点,如果链表中节点数为奇数,返回中间节点,如果为偶数,返回中间两个的任意一个
// 声明两个指针:p1+1, p2+2 --> p1
// 时间复杂度: O(n),空间复杂度:O(1)
ListNode<int>* GetListMiddleNode(ListNode<int>* pNode)
{
if (NULL == pNode)
{
return NULL;
} ListNode<int>* p1 = pNode;
ListNode<int>* p2 = pNode; while (p1 && p2)
{
//这两个顺序不能变,否则链表个数为奇数时,P1会多移动一位!!!
// p2 + 2
if (!p2->m_pNextNode)
{
break;
} p2 = p2->m_pNextNode->m_pNextNode; // p1 + 1
p1 = p1->m_pNextNode;
} return p1;
} void KthNodeFromEndTestFunc()
{
cout << "\n\n --------------- KthNodeFromEndTestFunc Start -------------->" << endl; int aiArray[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int iLen = sizeof(aiArray) / sizeof(int);
TRAVERSAL_ARRAY(aiArray, iLen); CSingleList<int>* pList = new CSingleList<int>();
if (!pList)
{
return;
} for (int i = 0; i < iLen; i++)
{
pList->Insert(aiArray[i]);
}
pList->Traversal(); int k = 16;
cout << "方法一: 打印链表倒数第K个数: " << endl;
ListNode<int>* pKNode = KthNodeFromEnd(pList->GetHeadNode(), k);
if (pKNode)
{
printf("倒数第%d个值为: %d\n", k, pKNode->m_stData);
} cout << "方法二: 打印链表倒数第K个数: " << endl;
pKNode = KthNodeFromEnd_2(pList->GetHeadNode(), k);
if (pKNode)
{
printf("倒数第%d个值为: %d\n", k, pKNode->m_stData);
} cout << "方法三: 打印链表倒数第K个数: " << endl;
pKNode = KthNodeFromEnd_3(pList->GetHeadNode(), k);
if (pKNode)
{
printf("倒数第%d个值为: %d\n", k, pKNode->m_stData);
} cout << "扩展一: 打印链表中间节点: " << endl;
pKNode = GetListMiddleNode(pList->GetHeadNode());
if (pKNode)
{
printf("链表中间%d个值为: %d\n", iLen / 2, pKNode->m_stData);
} // 释放内存
SAVE_DELETE(pList); cout << "\n\n --------------- KthNodeFromEndTestFunc End -------------->" << endl; }
题目15 链表中倒数第K个节点的更多相关文章
- 面试题 15:链表中倒数第 k 个结点
面试题 15:链表中倒数第 k 个结点 题目:输入一个链表,输出该链表中倒数第 k 个结点.为了符合大多数人的习惯, 本题从 1 开始计数,即链表的尾结点是倒数第一个结点.例如一个有 6 个结点的 链 ...
- 15:链表中倒数第K个节点
/** * 面试题15:链表中倒数第K个节点 * 输入一个链表,输出该链表中倒数第k个结点. */ public class _15_linked_K { public static void mai ...
- 剑指offer-第三章高质量的代码(输出该链表中倒数第K个节点)
题目:输入一个链表,输出这个链表中倒数第K个节点.(代码的鲁棒性) 思路:用两个指针p1和p2,都指向头节点,开始的时候,p2不动,p1移动k-1次,指向第k个节点.此时,如果p1->next! ...
- 链表中倒数第k个节点(Java)
链表中倒数第k个节点 题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路:two-pointers思想,因为是单链表,没法得prevous点,直接遍历得到链表长度再重新遍历效率很低. 采用双指 ...
- 《剑指offer》 链表中倒数第k个节点
本题来自<剑指offer> 链表中倒数第k个节点 题目: 输入一个链表,输出该链表中倒数第k个结点. 思路: 倒数第k个节点,而且只能访问一遍链表,定义两个节点,两者之间相差k个距离,遍历 ...
- 剑指offer(14)链表中倒数第K个节点
题目描述 输入一个链表,输出该链表中倒数第k个节点. 题目分析 用两个指针来跑,两个指针中间相距k-1个节点,第一个指针先跑,跑到了第k个节点时,第二个指针则是第一个节点. 这时候两个一起跑.当第一个 ...
- php实现求链表中倒数第k个节点
php实现求链表中倒数第k个节点 一.总结 $head = $head->next; //1.将$head节点next域里面的记录的那个地址值($head节点的下一个节点的地址)给$head,$ ...
- LeetCode 面试题22. 链表中倒数第k个节点
题目链接:https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/ 输入一个链表,输出该链表中倒数第 ...
- 【剑指Offer】面试题22. 链表中倒数第k个节点
题目 输入一个链表,输出该链表中倒数第k个节点.为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点.例如,一个链表有6个节点,从头节点开始,它们的值依次是1.2.3.4.5.6. ...
随机推荐
- python3 操作ppt
# pip install pywin32com# ppt太大会读取失败import win32com from win32com.client import Dispatch, constants ...
- 数据结构实验之栈与队列二:一般算术表达式转换成后缀式(SDUT 2132)
题目链接 #include <bits/stdc++.h> using namespace std; typedef long long ll; int ok(char ch, char ...
- windows游戏编程X86实模式和保护模式
本系列文章由jadeshu编写,转载请注明出处.http://blog.csdn.net/jadeshu/article/details/22309359 作者:jadeshu 邮箱: jades ...
- storm滑动窗口
Window滑动方式: 没有数据不滑动windowLength:窗口的时间长度/tuple个数slidingInterval:滑动的时间间隔/tuple个数 withWindow(Duration w ...
- 谈谈Java对象的强引用,软引用,弱引用,虚引用分别是什么
整体结构 java提供了4中引用类型,在垃圾回收的时候,都有自己的各自特点. 为什么要区分这么多引用呢,其实这和Java的GC有密切关系. 强引用(默认支持模式) 把一个对象赋给一个引用变量,这个引用 ...
- Python语法 - 推导式
推导式分为列表推导式(list),字典推导式(dict),集合推导式(set)三种 列表推导式(list comprehension)最擅长的方式就是对整个列表分别做相同的操作,并且返回得到一个新的列 ...
- golang中文件以及文件夹路径相关操作
获取目录中所有文件使用包: io/ioutil 使用方法: ioutil.ReadDir 读取目录 dirmane 中的所有目录和文件(不包括子目录) 返回读取到的文件的信息列表和读取过程中遇到的任何 ...
- 能不能支持在线查看word,excel这样的文件?还有拖拽上传功能?
https://forum.enhancer.io/topic/5adea0cdce69735af635fcd8 方法1. 用一个自定义窗口, 自定义窗口里放一个iframe 假设你的 word 的地 ...
- FMX开源控件
FMX开源控件 这是群友谢顿做的控件,必须赞一个! https://github.com/zhaoyipeng/FMXComponents 这是loki的: https://sourceforge.n ...
- smarty 模板几个例子(变量调节器)
一.assign和display方法的使用以及几个变量调节器 header("content-type:text/html;charset=utf-8");//加载Smarty引擎 ...