Cracking the coding Interview: ListNode
来源:互联网 发布:mac双系统修复windows 编辑:程序博客网 时间:2024/06/11 04:58
- Return kth to Last
- Delete Middle Node
- Partition
- palindrome
- Sum Lists
- Remove Dups
- Intersection
- Loop Detection
Return kth to Last
法一:就是计算有多少个节点,然后减去k,接着遍历。
class Solution {public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { int len = 0; if(pListHead == NULL) return NULL; ListNode* tmp = pListHead; while(tmp != NULL) { len++; tmp = tmp->next; } tmp = pListHead; int cnt = len - k; if(cnt < 0) return NULL; while(tmp != NULL && cnt-- != 0) tmp = tmp->next; if(tmp == NULL) return NULL; return tmp; }};
法二:
使用递归计算最后k个节点。
比如一个list是a->b->c->d。那么递归会一直调用到d,如果k为2,d调用的时候下一个为NULL,所以返回。这个时候cnt为1,不相等,就返回nd = NULL。然后到了c这一级,cnt = 2,满足条件,就把c这个节点的指针返回。到了d这一级,cnt为3,就把上次返回的结果返回。
class Solution {public: ListNode* kThLast(ListNode* p, unsigned int k, int &cnt) { if(!p) return NULL; ListNode* nd = kThLast(p->next, k, cnt); cnt++; if(k == cnt) return p; return nd; } ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { int i = 0; return kThLast(pListHead, k, i); }};
这里可以把程序写得更加规整一点,使用一个类。
class Index { public: unsigned int value = 0; };class Solution {public: ListNode* kThLast(ListNode* p, unsigned int k, Index* ind) { if(!p) return NULL; ListNode* nd = kThLast(p->next, k, ind); ind->value++; if(k == ind->value) return p; return nd; } ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { Index* ind = new Index(); return kThLast(pListHead, k, ind); }};
法三:快慢指针的使用
首先把一个指针指向第k个节点,然后另外一个节点从开头出发,第一个遍历的节点为遍历的结束的时候,第二个节点就正好到了最后的第k个元素。
class Solution {public: ListNode* FindKthToTail(ListNode* p, unsigned int k) { ListNode* p1 = p, *p2 = p; for(unsigned int i = 0; i < k ; i++) { if(p2) p2 = p2->next; else return NULL; } while(p2) { p1 = p1->next; p2 = p2->next; } return p1; }};
Delete Middle Node
使用快慢指针进行计算就可以得到所想要的结果。一个指向下一个,另外一个指向下下一个。
class Remove {public: bool removeNode(ListNode* p) { // write code here ListNode* p1 = p, *p2 = p; while(p2) { if(p2->next) p2 = p2->next->next; else break; p1 = p1->next; } return p1 != p2; }};
Partition
把一个List分成两个,左边小于x,右边不小于x。可以使用两个list存储,再进行合并。
class Partition {public: ListNode* partition(ListNode* pHead, int x) { // write code here ListNode* p1s = new ListNode(0), *p1e= NULL, *p2s = new ListNode(0), *p2e = NULL; while(pHead) { if(pHead->val < x) { ListNode *tmp = new ListNode(pHead->val); if(!p1e) { p1e = tmp; p1s->next = p1e; } else { p1e->next = tmp; p1e = tmp; } } else { ListNode *tmp = new ListNode(pHead->val); if(!p2e) { p2e = tmp; p2s->next = p2e; } else { p2e->next = tmp; p2e = tmp; } } pHead = pHead->next; } if(p1e) p1e->next = p2s->next; return p1e?p1s->next:p2s->next; }};
palindrome
这道题目就是求一个字符串是否是回文串。可以先找到中点,同时把前半部分压到栈中,再把栈中元素和后半部分作比较。
class Palindrome {public: bool isPalindrome(ListNode* pHead) { // write code here stack<int> stk; ListNode* p1 = pHead, *p2 = pHead; while(p1 && p1->next) { stk.push(p2->val); p1 = p1->next->next; p2 = p2->next; } if(p1 && !p1->next && p2) p2 = p2->next; p1 = pHead; while(p1 && p2) { int tp = stk.top(); if(tp == p2->val) stk.pop(); p1 = p1->next; p2 = p2->next; } return stk.empty(); }};
Sum Lists
求两个List的和。
class Plus {public: ListNode* plusAB(ListNode* a, ListNode* b) { // write code here ListNode* res = new ListNode(0); ListNode* tmp = res; int cf = 0; while(a || b || cf) { int t1 = (a?a->val:0), t2 = (b?b->val:0); int val = (t1 + t2 +cf)%10; cf = (t1 + t2 +cf)/10; ListNode* new_node = new ListNode(val); tmp->next = new_node; tmp = new_node; if(a) a = a->next; if(b) b = b->next; } return res->next; }};
Remove Dups
这道题目使用哈希表,那么就是计算复杂度O(n)和空间复杂度O(n)。
如果使用暴力破解,那么就是空间复杂度O(1)和时间复杂度O(n^2)。
Intersection
计算两个链表的交点,可以先遍历到底,比较最后的节点。或者先遍历其中一个链表,使最后的指针指向开始的节点。那么另外一个指针在遍历的时候,如果相交,那么就会到另外一个链表的起点。同时还可以使用哈希表存储各个节点的地址,不过地址大小的区别是一个问题,怎么设计映射函数。
Loop Detection
检测一个链表是否有环,一方面使用哈希表可以计算得到,另外一方面使用快慢指针如果在遍历结束之前找到发生相交即可。
- Cracking the coding Interview: ListNode
- Cracking the Coding Interview
- 《Cracking the coding interview》
- Cracking The Coding Interview
- Cracking the coding interview
- Cracking the coding interview
- Cracking the coding interview--Q1
- Cracking the coding interview--Q17
- Cracking the coding interview--Q2
- Cracking the coding interview--Q3
- Cracking the coding interview--Q4
- Cracking the coding interview--Q5
- Cracking the coding interview--Q8
- Cracking the coding interview--Q9
- Cracking the coding interview 题目
- Cracking The Coding Interview 1.1
- Cracking The Coding Interview 1.2
- Cracking The Coding Interview 1.3
- 1.13 06 循环数
- from __future__ import absolute_import用法心得小结
- 两会万花筒:人民政协报剪报
- 对一副扑克牌(大小王除外)运用洗牌算法洗牌--C语言版
- \n与\n\r的区别
- Cracking the coding Interview: ListNode
- 偷来的三分算法(苟神)
- LCA(模板)
- STM32F4应用笔记(二)利用蜂鸣器播放天空之城
- 阿里巴巴2017实习面试
- Java中Runnable和Thread的区别
- 《HeadFirst设计模式》读书笔记-第2章-观察者模式
- yolo在windows的运行实现
- centos安装ftp组件