public ListNode getKthFromEnd(ListNode head, int k) {
ListNode slow = head, fast = head;
for (int i = 1 ; i < k ; i ++) {
fast = fast.next;
}
while(fast.next != null) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
var getKthFromEnd = function(head, k) {
let dummy = new ListNode(0, head);
let fast = slow = dummy;
let index = k - 1;
while(index--) {
fast = fast.next;
}
while(fast.next !== null && slow.next !== null) {
fast = fast.next;
slow = slow.next;
}
return slow;
};
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getKthFromEnd(head *ListNode, k int) *ListNode {
if head == nil || k <= 0{
return head
}
//定义一个快指针fast,先走k个节点
//定义一个慢指针slow,等fast走k个节点后,一起出发
//1,2,3,4,5,6 k=2 ==》期待返回:5,6
//fast:3,4,5,6 slow:1,2,3,4,5,6
//fast:4,5,6 slow:2,3,4,5,6
//fast:5,6 slow:3,4,5,6
//fast:6 slow:4,5,6
//fast:nil slow:5,6
fast := head
slow := head
//fast先走k个节点
for i := 0; i < k; i++ {
fast = fast.Next
}
//等fast走k个节点后,一起出发
for fast != nil {
fast = fast.Next
slow = slow.Next
}
return slow
}
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
if head.val is None:
return head
t = head
for i in range(1,k):
t = t.next
if t.next is None:
return head
while t.next is not None:
head = head.next
t = t.next
return head
双指针,一个指针先走k步,之后两指针同时移动直到靠后的指针到链表末尾
时间复杂度: O(n)
空间复杂度:O(1)
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode pre = head;
ListNode now = head;
for(int i = 1 ; i<k ; i++){
now = now.next;
}
while(now.next != null){
pre = pre.next;
now = now.next;
}
return pre;
}
如果链表长度为 n,那么只要一个指针移动 n – k 次就能找到倒数第 k 个节点
双指针,fast先移动k个节点,然后fast和slow同时移动,最后返回slow
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head;
ListNode slow = head;
if (head == null) {
return null;
}
// fast 移动 k
for (int i = 0; i < k; i ++) {
fast = fast.next;
}
// fast 和 slow 同时向前移动
while (fast != null) {
fast = fast.next;
slow = slow.next;
}
return slow;
}
}
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
if not head:
return None
fast = head
while k > 0:
fast = fast.next
k -= 1
slow = ListNode()
slow.next = head
while fast:
fast = fast.next
slow = slow.next
return slow.next
# Definition for singly-linked list. 双指针
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
if not head:
return None
if not head.next:
return head
fast = head
slow = head
cnt = k
while cnt > 0:
fast = fast.next
cnt -= 1
while fast:
slow, fast = slow.next, fast.next
return slow
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
//相当于一个标志节点,让该标志节点和头节点一起向后遍历
ListNode flag = head;
for(int i = 0; i < k; i++){
flag = flag.next;
}
//当flag==null时,此时同步往后遍历的head就是要找的节点
while (flag != null){
flag = flag.next;
head = head.next;
}
return head;
}
}
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
int n = 0;
ListNode *p = head;
ListNode *result = head;
while(p != NULL){
n++;
p = p -> next;
}
for(int i = 0; i < n - k; i++){
result = result -> next;
}
return result;
}
};
剑指offer 双指针法 时间复杂度O(n) 空间复杂度O(1)
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
if(head == NULL) return head;
ListNode *fast = head;
ListNode *slow = head;
for(int i = 0; i < k; i++){
fast = fast -> next;
}
while(fast != NULL){
fast = fast -> next;
slow = slow -> next;
}
return slow;
}
};
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
if not head:
return None
slow = head
fast = head
step = k - 1
while step:
fast = fast.next
step -= 1
while fast.next:
slow = slow.next
fast = fast.next
return slow
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast = head;
for (int i = 1; i < k; i++) {
fast = fast.next;
}
ListNode low = head;
while (fast.next != null) {
low = low.next;
fast = fast.next;
}
return low;
}
}
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if (head == null) return null;
ListNode slow = head;
ListNode fast = head;
for (int i = 0; i < k; i++){
if (fast == null) {
return null;
}
fast = fast.next;
}
while (fast != null){
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
fast,slow=head,head
for i in range(k):
if fast:
fast=fast.next
else:
return fast
while fast:
fast=fast.next
slow=slow.next
return slow
js实现
var getKthFromEnd = function(head, k) {
// 双指针,指针距离是 k
let pre = head;
let next = head;
for(let i = 1; i < k; i++) {
next = next.next;
}
while(next.next ! null) {
pre = pre.next;
next = next.next
}
return pre;
};
# 遍历列表并删除值为val的节点
current = dummy_head
while current.next:
if current.next.val == val:
current.next = current.next.next
else:
current = current.next
return dummy_head.next
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode f = head;
ListNode s = head;
while(k-- > 0){
f = f.next;
}
while(f != null){
f = f.next;
s = s.next;
}
return s;
}
}
共以下 97 个回答
C++实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode getKthFromEnd(ListNode* head, int k) {
ListNode* pre=head;
ListNode* tmp=head;
while(k–) tmp=tmp->next;
while(tmp){
pre=pre->next;
tmp=tmp->next;
}
return pre;
}
};
方法:快慢指针
时间复杂度O(n)
空间复杂度为O(1)
倒数第k个=正数第 总个数+1-k 个
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode helper=head;
int num=0;
while(helper.next!=null){
helper=helper.next;
num++;
}
ListNode cur=head;
for(int i=1;i<=num+1-k;i++){
cur=cur.next;
}
return cur;
}
}
c++:
快慢指针
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode* fast=head;
ListNode* slow=head;
while(k–){
fast=fast->next;
}
while(fast!=NULL){
fast=fast->next;
slow=slow->next;
}
return slow;
}
};
”’java
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
//快慢指针
ListNode slow = head;
ListNode fast = head;
for(int i = 0;i < k;i++){
fast = fast.next;
}
while(fast != null){
slow = slow.next;
fast = fast.next;
}
return slow;
}
};
时间复杂度O(n)
空间复杂度O(1)
打卡
时间复杂度O(n),空间复杂度为O(1)
快慢指针
思路:快慢指针 + 虚拟头结点
代码
时间复杂度O(n)
空间复杂度O(1)
简单
”’java
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if(head null) {
return null;
}
ListNode pre = head;
ListNode post = head;
for(int i = 0; i < k && post != null; i++, post = post.next) ;
if(post null) {
System.out.println(“k的值大于链表的长度”);
return head;
}
while(post != null) {
}
”’
时间复杂度O(N), 空间复杂度O(1)
时间复杂度O(n)
空间复杂度O(1)
使用快慢指针,当快指针的next指向为None时,则到达最后k个节点,输出慢指针
时间复杂度O(n)
空间复杂度O(1)
先判断是否为空链表
设置快慢指针temp,pre
先将temp移到第k个节点
然后同步向后走,当temp为空时遍历完成,此时pre只想倒数第k个节点。
““java
class Solution{
public ListNode getKthFromEnd(ListNode head,int k){
if(head null)
{
return null;
}
ListNode fast = head, slow = head;
for(int i =0; i<k;i++){
if(fast null){
return null;
}
fast=fast.next;
}
while(fast!=null){
fast=fast.next;
slow=slow.next;
}
return slow;
}
}
时间复杂度0(n)
空间复杂度0(1)
fast比slow多走k步,然后slow和fast一起走,当fast等于null时,slow正好是倒数第k个节点
时间复杂度O(n)
空间复杂度O(1)
C++实现://思路转化成正着数第几个
//时间复杂度O(n)
Python 实现
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
former, latter = head, head
for _ in range(k):
former = former.next
while former:
former, latter = former.next, latter.next
return latter
双指针,一个指针先走k步,之后两指针同时移动直到靠后的指针到链表末尾
时间复杂度: O(n)
空间复杂度:O(1)
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode pre = head;
ListNode now = head;
for(int i = 1 ; i<k ; i++){
now = now.next;
}
}
如果链表长度为 n,那么只要一个指针移动 n – k 次就能找到倒数第 k 个节点
双指针,fast先移动k个节点,然后fast和slow同时移动,最后返回slow
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if (head null){
return head;
}
ListNode curr = head;
ListNode pre = head;
for(int i = 0; i < k; i++){
if (pre null) return null;
pre = pre.next;
}
while(pre != null){
pre = pre.next;
curr = curr.next;
}
return curr;
}
}
跟大家一样用的双指针解决这个问题,时间复杂度curr需要走n次,所以是O(n),空间复杂度使用常数大小的额外空间,所以是O(1)
快慢指针
有三种情况:
+ 链表为空,则返回空。
+ 链表长度小于k,则返回空。
+ 不是上述两种情况,则接着往后。
时间复杂度:O(n)。
空间复杂度:O(1)。
使用快慢指针,注意快指针先走K节点,然后快指针走完链表代表fast null
时间复杂度:o(n);
空间复杂度:o(1)
打卡
java语言,双指针
public ListNode getKthFromEnd(ListNode head, int k) {
//非空判断
if (head null){
return null;
}
// 定义头节点
ListNode headNode = new ListNode();
headNode.next = head;
// 定义快指针
ListNode fastNode = headNode;
// 定义慢指针
ListNode slowNode = headNode;
// 快指针多走K步
while (k-1!=0){
fastNode = fastNode.next;
k–;
}
//慢指针找到对应位置
while(fastNode.next!=null){
slowNode = slowNode.next;
fastNode = fastNode.next;
}
return slowNode;
}
空间复杂度O(1)
时间复杂度O(n)
时间复杂度:o(n);
空间复杂度:o(1)
时间复杂度:O(N)
空间复杂度:O(1)
打卡
使用双指针
时间复杂度O(N),空间复杂度O(1)
解题思路
单指针实现找到链表倒数第K个节点,首先通过设置一个指针,指针每移动一次节点个数+1,统计出节点的个数,然后根据倒数第k个数=n-k+1,按照这个从头往后遍历到倒数第k个数,遍历一个节点n-1,当n的值和k的值相同的时候就是指向了该节点
代码
时间复杂度O(n)
时间复杂度: O(n)
空间复杂度: O(1)
时间复杂度: O(n)
空间复杂度: O(1)
// 语言C++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode getKthFromEnd(ListNode* head, int k) {
int cnt=1;
ListNode* node0 = head;
while(node0->next!=nullptr){
node0=node0->next;
cnt++;
}
for(int i=1;i<=cnt-k;i++)
head=head->next;
return head;
}
};
时间复杂度O(n) 空间复杂度O(1)
通过快慢指针来完成函数,设置慢指针指向head,设置当前遍历的索引index=0,当满足条件 index + 1 > k 时,慢指针开始移动,slow = slow.next , 当快指针到达链表末尾时 head.next = null ,返回slow即为所求
时间复杂度 O(n) 空间复杂度O(1)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
if(head null || k <= 0 ){
return null;
}
ListNode indexNode = head;
int length = 0;
while(indexNode != null) {
length++;
indexNode = indexNode.next;
}
int counter = 1;
while(head != null){
}
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode temp=head, latter=head;
}
双指针,时间复杂度O(n),空间复杂度O(1)
剑指offer22 暴力解法 时间复杂度O(n) 空间复杂度O(1)
剑指offer 双指针法 时间复杂度O(n) 空间复杂度O(1)
双指针法。使用slow指针和fast指针分别指向头节点和头节点的后(k-1)个节点。当fast指针指向链表的最后一个节点时,slow指针指向链表的倒数第k个节点。
剑指 Offer 22. 链表中倒数第k个节点
双指针删除节点
时间复杂度:O(n)
空间复杂度:O(1)
时间复杂度 O(n),空间复杂度 O(1)
双指针
快慢指针
时间:O(n)
空间:O(1)
奇怪,为啥没有提交上
c++
使用前后指针,前指针先移动k步。
然后前后指针同时移动,保证前指针在空的时候,后指针在倒数第k个上
TC: O(n)
SC: O(1)
时间复杂度:O(n)
空间负责度:O(1)
时间复杂度为O(n)
空间复杂度为O(1)
【时间O(n),空间O(1)】
快指针先走k步
快慢指针一起走
当快指针走到末尾时,慢指针则走到倒数k个节点
时间复杂度O(n)
空间复杂度O(1)
时间复杂度On
空间O1
时间复杂度:O(n)
空间复杂度:O(1)
1、先判断链表是否为空
2、再创建快结点和慢结点
3、快结点先走k步,同时判断快结点是否为空,为空则返回null
4、在快结点不为空时,快慢结点一起往前走,最后返回慢结点即可
先设定符合题目的链表长度,再将尾指针向后移,就是内存占用有点大
struct ListNode* getKthFromEnd(struct ListNode* head, int k){
if(head NULL){
return NULL;
}
}
正着走k个之后,再走到头的步数n n+k就是总长度 第n个就是倒数第k个
“`C#
public class Solution {
public ListNode GetKthFromEnd(ListNode head, int k) {
ListNode fast = head;
ListNode slow = head;
}
“`
时间复杂度:O(n)
空间复杂度:O(1)
时间复杂度:O(n)
空间复杂度:O(1)
代码:
C++
执行用时:
8 ms
内存消耗:
10.3 MB
链表中倒数第K个节点:
双指针的方式:
设定一个指针指向该指针+k的节点处,使两个指针进行遍历,当快指针遍历完成后,直接返回慢指针即可。
思路:双指针p、q,p比q先行k步
注意:k大于链表长度的情况
时间复杂度:O(n)
空间复杂度:O(1)
思路:快慢指正思想,让快指针先走k步,然后快慢指针以前走,以慢指针为有节点返回结果链表。
class Solution:
def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
fast,slow=head,head
for i in range(k):
if fast:
fast=fast.next
else:
return fast
while fast:
fast=fast.next
slow=slow.next
return slow
“`c++
class Solution {
public:
// 快慢指针
// 时间复杂度 O(N),需遍历一次链表 N 个节点
// 空间复杂度 O(1)
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode* slow = head;
ListNode* fast = head;
};
“`
思路:双指针链表,快指针先走k步,然后快慢指针一起走,快指针走到最后时,慢指针走到倒数第k个
复杂度:时间复杂度为O(n),空间复杂度为O(1)
c++实现
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k){
% 链表是否为空
if(head nullptr) {
return nullptr;
}
ListNode* fastIndex = head;
ListNode* slowIndex = head;
% 快指针先走k步
for(int i=0; i<k; i++){
if(fastIndex nullptr) {
return nullptr;
}
fastIndex = fastIndex->next;
}
while(fastIndex != nullptr){
fastIndex = fastIndex->next;
slowIndex = slowIndex->next;
}
return slowIndex;
}
}
时间复杂度O(n),空间复杂度O(1)
c++实现
ListNode* dummphead = new ListNode(0);
dummphead->next = head;
ListNode* result = dummphead->next;
ListNode* slow = dummphead->next;
while(result!=NULL&&k–)
{
result=result->next;
}
while(result!=NULL)
{
slow = slow->next;
result=result->next;
}
return slow;
c++代码
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode* fast = head;
ListNode* slow = head;
for(int i=0; i<k; i++){
fast = fast->next;
}
while(fast!=nullptr){
fast = fast->next;
slow = slow->next;
}
return slow;
}
};
时间复杂度:O(n) 空间复杂度:O(1)
时间复杂度:O(n) 空间复杂度:O(1)
js实现
var getKthFromEnd = function(head, k) {
// 双指针,指针距离是 k
let pre = head;
let next = head;
for(let i = 1; i < k; i++) {
next = next.next;
}
while(next.next ! null) {
pre = pre.next;
next = next.next
}
return pre;
};
class Solution:
def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
# 创建虚拟头部节点以简化删除过程
dummy_head = ListNode(next = head)
使用C++实现
使用双指针,快指针先走K步,然后快慢指针同时进行,快指针到尾部时,返回慢指针位置,二者中间刚好差K
代码
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNode * former = head;
ListNode * later = head;
while(former&&(k>0)){
former = former->next;
k–;
}
while(former){
former = former->next;
later = later->next;
}
return later;
}
};
时间复杂度O(n)
空间复杂度O(1)
思路
代码
双指针
时间复杂度:O(n),空间复杂度:O(1)
快慢指针 快指针先走k步 当快指针走到末尾 慢指针刚好走到倒数第K个结点
“`c++
class Solution {
public:
ListNode* FindKthToTail(ListNode* pHead, int k) {
// write code here
//快慢指针 快指针先走k步 当快指针走到末尾 慢指针刚好走到倒数第K个结点
ListNode *fast = pHead;
while(k–)
{
if(fast == NULL) return NULL;
fast = fast->next;
}
while(fast){
fast = fast->next;
pHead = pHead->next;
}
return pHead;
}
};
“`
打卡
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode fast=new ListNode(-1);
fast=head;
ListNode slow=new ListNode(-1);
slow=head;
for(int i=0;i<k;i++){
fast=fast.next;
}
while(fast!=null){
fast=fast.next;
slow=slow.next;
}
return slow;
}
}
C++实现
··C++
public ListNode deleteNode(ListNode head, int val) {
ListNode temp=head;
if(temp.nextnull)return null;
if(temp.valval){
return temp.next;
}
while(temp.next!=null){
if(temp.next.valval){
temp.next=temp.next.next;
return head;
}
temp=temp.next;
}
return null;
}
···
C++实现
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
if(head NULL) return head;
ListNode* cur = new ListNode(0);
cur->next = head;
ListNode* tmp = new ListNode;
tmp->next = head;
int i = 0;
int j;
for(j = k;j > 0;j–){
tmp = tmp->next;
}
while(tmp->next != NULL){
cur = cur->next;
tmp = tmp->next;
}
return cur->next;
}
};
java实现
时间复杂度为n,空间复杂度为1.
思路:先让quick结点走k步,之后当quick为null,即走完的时候,slow结点就是倒数的第k个结点
c++ 实现
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
ListNodeslow = head;
ListNodefast = head;
k–;
while(k–){
fast = fast->next;
}
while(fast->next){
slow = slow->next;
fast = fast->next;
}
return slow;
}
};
class Solution{
public ListNode(ListNode head,int k ){
if(headnull){
return null;
}
ListNode fast=head,slow=head;
for(int i=0 i<k i++ ){
if(fastnull){
return null;
}
fast=fast.next;
}
while(fast!=null){
fast=fast.next;
slow=slow.next;
}
return slow
}
}
时间复杂度:O(n)
空间复杂度:O(1)
这里是Ming的打卡:
不涉及增删改,不建立虚拟头结点也能解决
解题方法:双指针,快的先走k步,之后咱俩就离k步举例同步走吧,保持举例挺好的
思路:双指针——快指针先走k步,然后快慢指针一起前进,当快指针达到尾部时,慢指针的位置即为倒数第k个节点的位置
时间复杂度:O(n),空间复杂度:O(1)
快慢指针
“`c++next;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/*
双指针,初始都直指向head,想让一个指针走k,这样两个指针之间就相差k步
两个指针,在同时向下移动,直到先走的指针为NULL,后走的指针就指向倒数第k个节点
*/
class Solution {
public:
ListNode* getKthFromEnd(ListNode* head, int k) {
if(head == NULL) return NULL;
ListNode* cur = head,*ans = head;
for(int i = 0;i
else return NULL;
}
while(cur!=NULL)
{
cur = cur->next;
ans = ans->next;
}
return ans;
};
“`