题目描述

输入一个链表,输出该链表中倒数第k个结点。

思路: 

两个指针,起始位置都是从链表头开始,第一个比第二个先走K个节点,当第一个走到链表尾时,第二个指针的位置就是倒数第k个节点。(两指针始终相聚k个节点)

注意边界条件:

1.链表不能一开始就是空的。

2.当链表只有5个节点时,若k=5,则返回第1个节点;若K>5,统一返回NULL。

边界条件十分影响case通过率!!!

#include "../stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
using namespace std; //链表基本操作:https://blog.csdn.net/wabil/article/details/65627058 //定义链表结构体类型
typedef struct TagList{
int val;
struct TagList *next;
}List; //创建链表
List *create_list(int val){
List *head = new List;
if (head == NULL){
return NULL;
}
head->val = val;
head->next = NULL;
return head;
} //插入节点数据(倒序插入)
List *insert_TagList(List *head, int val){
List *temp;
if (head == NULL){
return NULL;
} temp = new List; //与 List *temp = new List;有区别吗?
temp->val = val;
temp->next = head;
//head = temp; //head与temp地址相同,temp变化会立即引起Head值变化
//return head;
return temp;
} //打印链表倒数第k个节点(两个指针相隔k步,一个走到链表尾,另一个即处于倒数第k位)
List* FindKthToTail(List* pListHead, unsigned int k) {
List* pListHead1 = pListHead;
if (pListHead==NULL){
return nullptr; //判断非空
}
int i = ;
for (;pListHead != NULL; i++){ //同时满足两个条件
if (i > k){
pListHead1 = pListHead1->next;
}
pListHead = pListHead->next;
}
printf("\r\n %d", i); //for循环结束后,i=链表节点个数+1
if (i - < k){
return NULL; //边界条件:k>链表长度 (当5个节点的链表要返回第k(k>=6)个节点,统一返回NULL)
}
else{
return pListHead1;
}
} //反转链表
List* ReverseList(List* pHead) {
if (pHead == NULL){
return nullptr;
}
List *next = NULL;
List *pre = NULL;
while (pHead != NULL){
next = pHead->next; //预先存储下一个链表节点,防止反转时链表断裂
pHead->next = pre;
pre = pHead;
pHead = next;
}
return pre;
} //从尾到头打印链表
vector<int> printListFromTailToHead(List* head) {
//if (head == NULL){
// return -1;
//}//由于必须返回vector,这里直接过滤掉头为空的情况 //方法1:遍历链表,逆序插入vector
vector<int> array;
if (head != NULL){
while (head != NULL){
//array.insert(array.begin() + 3, head->val);//插入到第三个元素之后(即第四个元素,索引为3)
array.insert(array.begin(), head->val);//遍历节点,插入vector首位
head = head->next;
}
return array;
} ////方法2:翻转链表然后输出
//List *pre = ReverseList(head);
//vector <int> array;
//int i = 0;
//for (; pre != NULL; i++){
// //array[i] = pre->val; //vector不能按数组索引赋值,可以insert或者push_back
// array.push_back(pre->val);
// pre = pre->next;
//}
//return array;
} List* Merge(List* pHead1, List* pHead2)
{
/* //1.递归版本
if (pHead1 == NULL){ //边界条件非空判断
return pHead2;
}
if (pHead2 == NULL){
return pHead1;
}
List* pHead = NULL;
if (pHead1->val <= pHead2->val){
pHead = pHead1;
pHead->next = Merge(pHead1->next, pHead2);
}
else{
pHead = pHead2;
pHead->next = Merge(pHead1,pHead2->next);
}
return pHead; */ //2.非递归版本
if (pHead1 == NULL){ //边界条件非空判断
return pHead2;
}
if (pHead2 == NULL){
return pHead1;
} //List* pHead = new List; //Oxcccc<val=?? next=??>
//List* pHead = NULL; //0x000<NULL>
//定义为NULL后无法添加val,next属性(pHead->val=3;之类会报错)
//但是可以将链表整个赋给空节点(如pHead=pHead1; pHead=pHead1->next;) //List *pHead=new List;
//List *current = pHead; //是指向同一个地址还是指内容?? List *pHead = NULL;
List *current = NULL; while (pHead1 != NULL && pHead2 != NULL){
if (pHead1->val <= pHead2->val){
//pHead->val = pHead1->val; if (pHead == NULL){
pHead = current = pHead1;
}
else{
current->next = pHead1;
current = current->next;
}
pHead1 = pHead1->next;
}
else{
//pHead->val = pHead2->val; if (pHead == NULL){
pHead = current = pHead2;
}
else{
current->next = pHead2; //pHead也会一起变化, 整个过程中current作用???
current = current->next;
}
pHead2 = pHead2->next;
}
//pHead = pHead->next;//相当于去掉之前的一个节点,进入到下一个节点
}
if (pHead1 != NULL){
current->next = pHead1; //当其中一个遍历完了的时候,直接将合并链表的next指向非空链表
}
else{
current->next = pHead2;
}
return pHead;
} int main(void){
int i = ;
List *head = create_list();
List *buf; /* //倒序插入节点
for (i = 1; i <= 10; i++){
head = insert_TagList(head, 100 + i);
}
i = 0;
buf = head;
cout << "\n倒序插入节点:"<<endl;
while (buf != NULL){
printf("Data[%02d]:%d \n", i++, buf->val);
buf = buf->next;
}*/ /* //输出倒数第K个节点
head = FindKthToTail(head, 12);
printf("\r\nData:%d", head->val);*/ /* //翻转链表
i = 0;
buf = ReverseList(head);
cout << "\n翻转链表:" << endl;
while (buf != NULL){
printf("reverse data[%02d]:%d \r\n", i++, buf->val);
buf = buf->next;
}*/ /* //链表从尾到头进行打印
vector<int> vec = printListFromTailToHead(head);
vector<int>::iterator it;
cout << "\n从尾到头进行打印:\n";
for (it = vec.begin(); it != vec.end(); it++)//遍历输出vector
{
cout << *it << endl;
}*/ // 2个链表倒序插入节点
List *head1 = create_list();
head1 = insert_TagList(head1, );
head1 = insert_TagList(head1, );
List *head2 = create_list();
head2 = insert_TagList(head2, );
head2 = insert_TagList(head2, ); /*for (i = 5; i > 0; i--){
head = insert_TagList(head, 90 + i); //91-95, 100
}
List *head1=head;
for (i = 5; i > 0; i--){
head = insert_TagList(head, 80 + i); //81-85,91-95,100
}
List *head2 = head;*/ List *head3 = Merge(head1,head2);
i = ;
cout << "\n 合并两个有序链表:" << endl;
while (head3 != NULL){
printf("Data[%02d]:%d \n", i++, head3->val);
head3 = head3->next;
} getchar();
return ;
}

参考://https://blog.csdn.net/wabil/article/details/65627058

 

2.链表之判断两个单链表相交的位置

链表相交是指存储相同val的地址也要相同,而不是仅仅val相同。

思路:

如果用两个while(head !=NULL)是无法遍历的,因为内循环指针到链表节点末尾的时候,指向为空,不能自动回到表头。

这里 是用p,q代替两个表头;且一个到链表尾的时候就指向另一个的表头,来进行遍历的。

class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA==NULL or headB==NULL){
return NULL;
}
else{
ListNode *p=headA;
ListNode *q=headB;
while(p!=q){
if(p!=NULL){
p=p->next;
}
else{
p=headB;
}
if(q!=NULL){
q=q->next;
}
else{
q=headA;
}
}
return p;
}
}
};
 

[剑指offer] 14. 链表中倒数第K个节点+翻转+逆序打印+合并两个排序链表 + 链表相交(第一个公共节点) (链表)的更多相关文章

  1. [剑指Offer]22-链表中倒数第k个结点

    题目链接 https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&t ...

  2. 剑指Offer面试题15(Java版):链表中倒数第K个结点

    题目: 输入一个链表.输出该链表中倒数第k哥结点.  为了符合大多数人的习惯,本题从1開始计数.即链表的尾结点是倒数第1个结点. 比如一个链表有6个结点.从头结点開始它们的值依次是1.2.3,4,5, ...

  3. 剑指offer例题——链表中倒数第K个结点

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 编程过程 此处采用两个指针依次后移的方法来求解,首先,用一个指针移到第k个位置,之后将第二个指针放在第一位,与第二个指针一同移动,当第二个指针移动 ...

  4. 剑指offer——24链表中倒数第k个结点

    题目描述 输入一个链表,输出该链表中倒数第k个结点.   题解: 1.普通解法,先遍历一遍计算链表长度,然后遍历到倒数第k个节点: 2.只遍历一遍,使用双指针,使得头尾指针位差为k,那么当尾指针为空时 ...

  5. 14.链表中倒数第k个节点

    题目描述:   输入一个链表,输出该链表中倒数第k个结点. 思路分析:   设置两个指针,一个fast一个slow,都从链表头开始,让fast先走k步,然后两个指针一起走,当fast走到尾部,那么sl ...

  6. 剑指Offer 14. 链表中倒数第k个结点 (链表)

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 题目地址 https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?t ...

  7. 剑指offer 14. 链表中倒数第 k 个结点

    14. 链表中倒数第 k 个结点 题目描述 输入一个链表,输出该链表中倒数第k个结点 法一:快慢指针 快指针先走 k 步,等快指针到达尾部时,慢指针所指结点即是倒数第 k 个结点 public cla ...

  8. 剑指offer 14:链表中倒数第k个节点

    题目描述 输入一个链表,输出该链表中倒数第k个结点. /* public class ListNode { int val; ListNode next = null; ListNode(int va ...

  9. 剑指offer——python【第14题】链表中倒数第k个节点

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路 注意,看清楚,是输出节点,而不是输出节点值 可以先求出链表总长度,然后正向遍历得到第n个节点 解答 class Solution: def ...

随机推荐

  1. python之简述上下文管理

    上下文管理器 原理 代码讲解 原理 上下文管理能保证资源会被正确回收,即保证退出步骤的执行.其用处最多的是,作为确保资源被正确回收的一种方式. 一种重复使用的 try-except-finally 结 ...

  2. Django入门--模型系统(二):常用查询及表关系的实现

    1.常用查询 模型类上的管理器: ** 模型类.objects ** (1)常用一般查询 rs = Student.objects.all() # 查询所有记录,返回Queryset print(rs ...

  3. 邓_ Php·面试

    1:PHP的意思,它能干什么?       PHP是一个基于服务端来创建动态网站的脚本语言,您可以用PHP和HTML生成网站主页,英文的全称(Professional Home Pages)1.Web ...

  4. 深入MNIST code测试

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50624471 依照教程:深入MNIST ...

  5. Tsinsen A1206. 小Z的袜子

    /* Tsinsen A1206. 小Z的袜子 http://www.tsinsen.com/new/A1206 BZOJ 2038: [2009国家集训队]小Z的袜子(hose) http://ww ...

  6. 开启WIFI

    C:\Windows\system32>netsh wlan set hostednetwork mode=allow ssid=wuyechun-wifi k ey= 承载网络模式已设置为允许 ...

  7. Quartz.Net 使用心得(一)

    最近工作内容与定时任务相关,在实际使用Quartz过程中,有两个小问题较为困扰. 一.多个Trigger如何触发一个Job. 比如上下班打卡时推送消息,上班时间为9:30,打卡提醒时间为9:20较好. ...

  8. 【云快讯】之四十八《IBM和Cisco最新收购,加强Openstack易用能力》

    2015-06-08 张晓东 东方云洞察 点击上面的链接文字,能够高速关注"东方云洞察"公众号 本周宣布的两起收购引人注意.思科购买Piston云计算公司.同期IBM的收购Blue ...

  9. 2015.04.21,外语,读书笔记-《Word Power Made Easy》 12 “如何奉承朋友” SESSION 32

    TEASER PREVIEW 如何描述这些人: 很友好.容易相处的人: 不知疲倦的人: 简单.直率..aboveboard([ə'bʌv'bɔ:d] adv. 光明正大地, 率直地 adj. 光明正大 ...

  10. nyoj--74--小学生算术(水)

    小学生算术 时间限制:3000 ms  |  内存限制:65535 KB 难度:1 描述 很多小学生在学习加法时,发现"进位"特别容易出错.你的任务是计算两个三位数在相加时需要多少 ...