剑指offer 14、链表中的倒数第k个节点 python c++
题目描述:
输入一个链表,输出该链表中倒数第k个结点。
翻车思路:把链表倒序,然后找到底k个节点,返回即可。
为啥会翻车:我以为是返回倒是第k个节点,输出它的值。结果这题目要输出的是原来链表的倒数第k个及以后的节点。
举个例子,用例:{1,2,3,4,5},3,意思是返回倒数第三个节点对应输出应该为: {3,4,5},而不是{3}
就当复习一遍链表倒序吧。
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# write code here
#反转链表
print(head.val)
if head is None : #排除没有元素和只有一个元素
return None
if head.next is None:
return head.next
#python里面居然head就是第一个节点,见鬼了
p1 = head #代表原始的第一个节点
p2 = p1.next #代表要放到最前面(head后面)的节点
p3 = None #这儿不等于p2.next是因为怕只有两个元素 ,它的含义是下一个放到最前面(head后面)的节点,
while p2!= None:
p3 = p2.next; #找到当前的p3
p1.next = p3; #第一个节点的后续节点指向下一个要放到最前面节点p3
p2.next = head; #本次要节点p2放到最前面,那么原来的最前面就变成本次要放到最前面节点p2的后续节点
head = p2; #头结点的后续节点指向本次要放到最前面节点p2
# 这样一来,p3前面的节点都是倒序了的
p2 = p3; #然后当前的p3就变成下一个要放到前面(head的后续节点)的节点p2,进行下一次循环
p = head
for i in range(k-1): #从倒数一到倒数第k,只要k-1次就好了
p = p.next
return p
#我靠,这题目要输出的是原来链表的倒数第k个及以后的节点。麻蛋,这题目也不说清楚
#我以为是返回倒是第k个节点,输出它的值。
换思路,既然要输出原来链表的倒数第k个及以后的节点。那么原来的指向关系不能变,快慢指针可以搞定这个事。
c++版
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead == nullptr || k < 1){
return nullptr;
}
ListNode *p = pListHead;
while(k-- != 0){
if(p == nullptr){ //怕总的节点个数都没有k个
return nullptr;
}
p = p->next;
}
while(p != nullptr){
p = p->next;
pListHead = pListHead->next;
}
return pListHead;
}
};
这儿是用来原来的head指针做为慢指针了,你也可以自己定义一个慢指针,比如
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
if(pListHead == nullptr || k < 1){
return nullptr;
}
ListNode *faster = pListHead;
ListNode *lower = pListHead;
while(k > 0){
if(faster == nullptr){
return nullptr;
}
faster = faster->next;
--k;
}
while(faster != nullptr){
faster = faster->next;
lower = lower->next;
}
return lower;
}
};
python版
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# write code here
if head == None or k < 1:
return None
faster = head
lower = None
for i in range(k-1):
if faster.next != None:
faster = faster.next
else:
return None
lower = head
while faster.next != None:
faster = faster.next
lower = lower.next
return lower
Python版2
这个是利用python里面的列表元素可以是任意的类型这个特点,把节点(一个值和一个下一个节点的地址)作为一种类型放到列表里面
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def FindKthToTail(self, head, k):
# write code here
res=[]
while head:
res.append(head)
head=head.next
if k>len(res) or k<1:
return
return res[-k]
为什么可以呢,是因为我们返回的元素是一个节点型的(我瞎起的名字),里面包括了一个值和一个地址(下一个节点的位置),根据这两个东西我们就能找到 原来链表的倒数第k个及以后的节点。因为我们没有改指向关系,像我第一次逆序的话就是改变了指向关系,所以没过