剑指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个及以后的节点。因为我们没有改指向关系,像我第一次逆序的话就是改变了指向关系,所以没过

posted on 2021-06-10 17:24  雾恋过往  阅读(48)  评论(0编辑  收藏  举报

Live2D