双指针。先让一个指针顺著链表走n次,然后再让一个指针从头开始走。然后两个指针同时顺链表走,直到第一个指针走到链表尾部,此时第二个指针的位置就是倒数第n个节点。
1.单链表:先遍历一遍,从遍历的内容获取。
2.双向链表:遍历到最后,往回倒n个
3.循环单链表:跟单链表一样
4.循环双链表:往后遍历n个
双指针
第一个指针走n步
然后第二个指针从头开始,两个指针一起走,
当第一个指针指到最后的时候,第二个指针正好指向倒数n个节点
单链表的话,一般用双指针是最优解:O(1)空间,O(n)时间。
但我有一个骚操作——递归。O(2n)时间,O(1)空间(不考虑调用栈。考虑的话则是O(n))
考虑单链表是一棵每个结点只有右(或者左)子树的二叉树,那么可以使用后根遍历的方式来处理。代码如下:
private static void getNthFromLast(ListNode head, ListNode[] ret, int[] n) {
if (head == null || ret[0] != null) {
return;
}
getNthFromLast(head.next, ret, n);
if (—-n[0] == 0) {
ret[0] = head;
}
}
public static ListNode getNthFromLast(ListNode head, int n) {
if (n &<= 0 || head == null) {
return null;
}
ListNode[] ret = new ListNode[1];
getNthFromLast(head, ret, new int[]{n});
return ret[0];
}
姑且尝试解答这个问题,仅供参考!
什么是链表 ?
链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个「头指针」变数,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为「结点」,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为「表尾」,它的地址部分放一个「NULL」(表示「空地址」),链表到此结束。
8种链表
节点结构
typedef struct SListNode
{ SDataType _data;
struct SListNode* _PNext;
}Node,*PNode;
如何获取倒数第n个元素(以非循环单链表为例)?
① 首先获取到总的元素个数为 m
方法:从表头开始遍历,直到最后一个节点。
② 然后用 m -n +1, 得到的就是从表头开始的元素,也就是相当于倒数第n个元素。
如下图:
③程序实现
求总的节点数 m :
int m = 0;
struct student *p = head;
if(head != NULL)
{
do
{
m++;
p = p-&>next; //移到下一个节点
}
while (p != NULL);
}
再正向遍历
int i = 0;
struct student *p = head;
if(head != NULL n &<= m)
{
do
{
i++;
if(i == m-n+1)
{
printf("%d
", p-&>_data);
break;
}
p = p-&>next; //移到下一个节点
}
while (p != NULL);
}
逆向的话,可能需要双向链表了,比较方便。
代码比较草稿,记事本写的,仅供参考。
谢邀,我想了一下,大概有如下几种方式:
迭代整个链表,把每个元素加入到栈中,最后一次从上往下从栈中取出n个元素即可
换个思路,反转链表,然后从前往后数n个元素即可
迭代一遍计算链表的长度len,然后计算出len-n,然后第len-n+1个元素即是我们想要的元素
使用双指针,指针a跟指针b,指针a先向前走n步,然后a跟b开始同步移动,当a走到末尾时,b的下一个元素即是我们要找的元素
再次谢邀,我平时也有在整理一些演算法相关的思路跟套路,有兴趣的可以看看我的专栏:
一道题做一宿?
zhuanlan.zhihu.com
双指针第一个指针先走n步就行了,我记得leetcode上有原题
pointer1=head
pointer2=head
p1_pos = 0
# You can use while p1_pos &< n and pointer1 to prevent from n &> listnode_length
while p1_pos &< n:
pointer1 = pointer1.next
p1_pos += 1
# after this while loop, pointer1 is in nth position, now start to move both pointer1 and 2 together
# if next element is not None
while pointer1.next:
pointer1 = pointer1.next
pointer2 = pointer2.next
# if pointer1 reaches to the end, pointer2 is in listnode_length - n pos
return pointer2
没用ide,直接在知乎回答框写的python代码,缩进之类的东西可能有问题.
也懒得写def结构什么的了..反正python是最像伪代码的代码, head是首节点. node.next是当前节点的下一个节点
双指针很简单啊
先让第一个指针提前走n步
然后第一、二个指针再同时走,直到指针一到达链表末尾,这时候指针二的位置就是倒数第n个元素的位置
推荐阅读:
Please enable JavaScript to view the comments powered by Disqus.