划水总结剑指offer 链表系列1
最近在找实习,发现面试题和oj的题差距蛮大的,然后粗略的刷了一遍剑指offer.希望6月中旬前能拿个实习(捂脸哭)
1.首先总结关于链表的题.
(1)从尾到头打印一个链表.像我这样的憨憨上来就想 这不是反向链表然后打印吗.此题并没有要翻转这个链表,而是可以递归的将链表的值倒序输出即可.
class Solution {
public:vector<int> ans;void diguiPrint(ListNode * p){if(!p)return;diguiPrint(p->next);ans.push_back(p->val);}vector<int> printListFromTailToHead(ListNode* head) {diguiPrint(head);return ans;}
};
接下来面试官大大说,你能不用递归吗?
然后我们用头插法做一个反向新链表
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:vector<int> ans;vector<int> printListFromTailToHead(ListNode* head) {if(!head) return ans;ListNode * newHead=new ListNode(0);ListNode * p=newHead;while(head){ListNode * temp=new ListNode(head->val);if(p->next)temp->next=p->next;p->next=temp;head=head->next;}p=p->next;while(p){ans.push_back(p->val);p=p->next;}return ans;}
};
然后hr小哥哥说,这也太麻烦了,再造一个链表属实憨憨.
最后我们考虑一下用栈存一下节点指针~
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:vector<int> ans;vector<int> printListFromTailToHead(ListNode* head) {stack<ListNode * >sta;while(head){sta.push(head);head=head->next;}while(!sta.empty()){ans.push_back(sta.top()->val);sta.pop();}return ans;}
};
(2)链表中的倒数第k个节点
HR哥哥说 要求你最多走一遍链表.这时你想到了快慢指针,我整俩指针,一个比另一个先走k不就完事儿了吗
/*
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==NULL||k<=0)return NULL;ListNode * p1,*p2;p1=p2=pListHead;while(p1&&k){p1=p1->next;k--;}if(k==0){while(p1){p1=p1->next;p2=p2->next;}return p2;}return p1;}
};
这时候海哥小声嘀咕...我以前都是整个指针队列来解的.感觉这样更不容易错.再写一遍好咯..
/*
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==NULL||k<=0)return NULL;queue<ListNode *> que;while(pListHead){if(que.size()==k)que.pop();que.push(pListHead);pListHead=pListHead->next;}if(que.size()==k)return que.front();else return NULL;}
};
海哥你真是飞舞..连个实习都找不到,你这样怎么能得到五花肉的芳心?
那我再看几个题好了,下周还有面试机会,别骂了别骂了 再骂人傻了.
(3)翻转链表
依稀记得以前应翔老师(曾经是最年轻(28)的副教授据说)说过,涉及到链表一定要考虑清楚,要是实在笨可以画图...应大佬好像去创业了....不知道有没有机会讨要一纸张offer...
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}
};*/
class Solution {
public:ListNode* ReverseList(ListNode* pHead) {ListNode* temp,*last;last=NULL;while(pHead){temp=pHead->next;pHead->next=last;last=pHead;pHead=temp;}return last;}
};
要个球.翻转个链表都能经常错.......应该用栈压进去然后取出来的时候更新next也能很简单的过吧....但是估计会被hr笑死....
(4)合并两个排序的链表....又因为返回的时候忘了返回的应该是创建的节点的下一个节点而错了....我完了 我是飞舞
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {}
};*/
class Solution {
public:ListNode* Merge(ListNode* pHead1, ListNode* pHead2){ListNode * p=new ListNode(0);ListNode * ans=p;while(pHead1&&pHead2){if(pHead1->val<=pHead2->val){ans->next=pHead1;pHead1=pHead1->next;}else{ans->next=pHead2;pHead2=pHead2->next;}ans=ans->next;}while(pHead1){ans->next=pHead1;ans=ans->next;pHead1=pHead1->next;}while(pHead2){ans->next=pHead2;ans=ans->next;pHead2=pHead2->next;}return p->next;}
};
(5)复杂链表的复制
这个题看起来好像没什么简单的解法?先常规,用个map/hashmap存一下旧节点和新节点的对应,然后第二次遍历的时候加random指针.
/*
struct RandomListNode {int label;struct RandomListNode *next, *random;RandomListNode(int x) :label(x), next(NULL), random(NULL) {}
};
*/
class Solution {
public:RandomListNode* Clone(RandomListNode* pHead){if(pHead==NULL)return pHead;RandomListNode * ans=new RandomListNode(0);RandomListNode * tempans=ans;RandomListNode * tempHead=pHead;map<RandomListNode*,RandomListNode*> m;while(tempHead){RandomListNode * temp=new RandomListNode(tempHead->label);m.insert(make_pair(tempHead,temp));tempans->next=temp;tempans=tempans->next;tempHead=tempHead->next;}tempans=ans;tempans=tempans->next;tempHead=pHead;while(tempHead){if(m.find(tempHead->random)!=m.end()){tempans->random=m.find(tempHead->random)->second;}tempans=tempans->next;tempHead=tempHead->next;}return ans->next;}
};
这时候hr小哥又说了,你能不用map吗???????
这时候我一脸无奈,满足你的任性好了(逃,日常哭泣,到处都是bug)此时你想了想,如果是数组的话,复制就没这么麻烦了,不能挨个直接复制的原因是什么呢?当你到第k个节点的时候,random可能指向后面,所以你没办法这样创建,map也就是帮你把映射关系存下来最后加random指针而已,你完全可以遍历的时候直接在a后插入新的a,这样加random的映射就是a->random->next就是你要的random的复制出来的节点辣.....我是飞舞 我没想出来.....(爆哭)
/*
struct RandomListNode {int label;struct RandomListNode *next, *random;RandomListNode(int x) :label(x), next(NULL), random(NULL) {}
};
*/
class Solution {
public:RandomListNode* Clone(RandomListNode* pHead){if(pHead==NULL)return NULL;RandomListNode * tempHead=pHead;while(tempHead){RandomListNode * tempNode=new RandomListNode(tempHead->label);tempNode->next=tempHead->next;tempHead->next=tempNode;tempHead=tempNode->next;}tempHead=pHead;while(tempHead){if(tempHead->random)tempHead->next->random=tempHead->random->next;tempHead=tempHead->next->next;}RandomListNode * ans=new RandomListNode(-1);RandomListNode * tempans=ans;tempHead=pHead;while(tempHead){tempans->next=tempHead->next;tempans=tempans->next;tempHead=tempHead->next->next;}pHead->next=NULL;return ans->next;}
};
这题有个超级恶心的坑.这题是怎么检测你是否直接返回了给你的指针?它竟然真的是直接拿自己的指针寻找有没有访问到你返回来的这些地址,QAQ我人傻了....知道了这个坑 应该能很快写出来吧233
(6)二叉搜索树与双向链表
水题.写了递归,然后HR说,递归的本质是什么? (...我也不知道哇).
/*
struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};*/
class Solution {
public:TreeNode* Convert(TreeNode* pRootOfTree){if(pRootOfTree==NULL)return NULL;TreeNode * left=Convert(pRootOfTree->left);TreeNode * right=Convert(pRootOfTree->right);TreeNode * leftright=left;while(leftright&&leftright->right){leftright=leftright->right;}if(leftright)leftright->right=pRootOfTree;pRootOfTree->left=leftright;pRootOfTree->right=right;if(right)right->left=pRootOfTree;if(left)return left;return pRootOfTree;}
};
划水总结剑指offer 链表系列1相关推荐
- 递增的整数序列链表的插入_每日算法题 | 剑指offer 链表专题 (5)链表中倒数第k个节点...
点击上方"Jerry的算法和NLP",选择"星标"公众号 重磅干货,第一时间送达 题目 链表中倒数第k个节点 题目要求 输入一个链表的头结点,从尾到头反过来打印 ...
- 剑指offer试题系列
剑指offer之题目5 题目描述: 请实现一个函数,将一个字符串中的每个空格替换成"%20".例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%2 ...
- 剑指 offer 链表倒数的第k个数
快慢指针 快指针线遍历到第k-1个数,然后慢指针在从头开始遍历,这样快慢指针有k-1个间隔,当快指针到链表末尾时,慢指针指的数就是倒数第k个数. public class Solution { ...
- 剑指Offer——链表中倒数第K个节点
1.题目描述 输入一个链表,输出该链表中倒数第k个结点. 2.代码实现 package com.baozi.offer;/*** @author BaoZi* @create 2019-07-11-1 ...
- 剑指offer 链表中倒数第k个节点
题目描述 输入一个链表,输出该链表中倒数第k个结点. 解决方案: public class Solution {public ListNode FindKthToTail(ListNode head, ...
- python删除链表的倒数第k个节点,剑指offer 链表中的倒数第K个节点 Python and C++
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路 假设链表中的节点数大于等于k个,那么一定会存在倒数第k个节点,首先使用一个快指针先往前走k步,然后两个指针每次走一步,两个指针之间始终有k的 ...
- 剑指Offer——链表中环的入口结点
题目描述: 一个链表中包含环,请找出该链表的环的入口结点. 分析: 设置两个指针p1,p2, 两个指针都从链表的头部开始走,不过p1每次走一步,p2每次走两步. 直到相遇的时候,p2走的长度是p1的两 ...
- Java解析剑指Offer链表篇(1)
目录 一.移除链表元素 1.题目要求 2.基本思路 3.代码演示 二.反转链表 1.题目要求 2.基本思路 3.代码实现 三.链表的中间结点 1.题目要求 2.基本思路 3.代码实现 四.链表中倒数第 ...
- 剑指Offer对答如流系列 - 用两个栈实现队列
面试题8:用两个栈实现队列 一.题目描述 用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 二 ...
最新文章
- jQuery ajax 传递JSON数组到Spring Controller
- 我知道今天是写总结的日子-所以买了一罐啤酒喝
- SSM实现个人博客系统
- 全网独发gensim中similarities.Similarity用法
- ACE框架解读 - 源码篇
- 基于SVD矩阵分解的用户商品推荐(python实现)
- 饿了么ui组件中分页获取当前选中的页码值_【Web技术】314 前端组件设计原则
- SAP Spartacus里px,em和rem的应用
- java集合set的使用_浅析Java中的set集合类型及其接口的用法
- 1268:【例9.12】完全背包问题
- phpcms能做什么呢?有什么作用呢?
- 支付宝架构师的总结:为什么他们能抗住万亿级流量的高并发?
- mysql--------常用命令
- LINUX下载编译libc(glibc)
- loadrunner 打印变量
- 机器学习之层次聚类及代码示例
- 阿里云centos 7下kubeadm方式安装kubernetes 1.14.1集群(包含解决墙以及各种坑的问题)
- mmdetection源码笔记(一):train.py解读
- 二维泊松方程数值解-五点差分法-共轭梯度法-python实现
- C++的一个指针占内存几个字节?