cycle,reverse,rotate linked list
来源:互联网 发布:欧文生涯数据统计 编辑:程序博客网 时间:2024/05/22 11:37
Linked List Cycle
Given a linked list, determine if it has a cycle in it.
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: bool hasCycle(ListNode *head) { if(head == NULL || head->next == NULL) return false;ListNode* h = head;ListNode* p = head;while(p->next != NULL && p->next->next != NULL)//注意直接是对走两步的进行判断就好,如果结束,两步的先结束,{h = h->next;p = p->next->next;if(p == h) return true;}return false; }};
Linked List Cycle II
null
.两个节点,一个快节点(q)每次走两步,一个慢节点(p)每次走一步,如果有环相遇时候,q走得路程是p的两倍
q = x + y + z + y =2p =2(x + y),x起点到环路开始距离,y 环路开始到相遇点距离,z相遇点到环路开始距离
class Solution {public: ListNode *detectCycle(ListNode *head) { if(head == NULL || head->next == NULL)return NULL; ListNode* p = head; ListNode* q = head; bool flag = false; while(q != NULL && q->next != NULL) { q=q->next->next; p=p->next; if(p == q) { p=head; while(p!=q) { p = p->next; q = q->next; } return p; } } return NULL; }};
Reverse Linked List II
Reverse a linked list from position m to n. Do it in-place and in one-pass.
主要思想就是边遍历边改变指针,使得在m,n之间的节点指向他们的前一个节点,最后再更改m-1和n+1的指针指向
我翻转链表的方法是往后走,有点复杂,涉及k的判断可能越界
class Solution {public: ListNode *reverseBetween(ListNode *head, int m, int n) { if(head == NULL || m == n) return head; ListNode* guard = new ListNode(0); guard->next = head; ListNode* h = guard; ListNode* p = guard; ListNode* q = guard; ListNode* k = guard; int c = 0; while(c!=m) { ++c; h = p; p = p->next; } q = p->next; k = p->next->next; while(c!=n) { ++c; q->next = p; p = q; q = k; if(k!=NULL)k = k->next; } h->next->next = q; h->next = p; return guard->next; }};
修改的新代码如下
主要在反转的时候,注意添加pre节点,p当前节点,q是下一个节点,这样子迭代就只是当前节点和下一个节点和一个已经处理了的节点,简洁多了。
class Solution {public: ListNode *reverseBetween(ListNode *head, int m, int n) { if(head == NULL || m == n) return head; ListNode* guard = new ListNode(0); guard->next = head; ListNode* h = guard; ListNode* p = guard; ListNode* q = guard; ListNode* pre = NULL; int c = 0; while(c!=m) { ++c; h = p; p = p->next; } while(c<=n) { ++c; q = p->next; p->next = pre; pre = p; p = q; } h->next->next = p; h->next = pre; return guard->next; }};
Reorder List
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
举个例子,1>2>3>4>5>6>7 ——> 1>7>2>6>3>5>4,找到中间点4
1>2>3>4> 1>2>3>4>
>5>6>7 ——> >7>6>5 4之后的节点翻转,然后依次链接到前面的链表中
class Solution {public: void reorderList(ListNode *head) { if(head == NULL || head->next == NULL || head->next->next == NULL)return;ListNode *mid,*p,*q,*k;mid=p=q=k=head;while(p!=NULL && p->next!=NULL){p = p->next->next;mid = mid->next;}p = mid->next;if(p->next!=NULL){q = p->next;k = q->next;p->next = NULL;if(k==NULL){q->next = p;}while(k!=NULL){q->next = p;p = q;q = k;if(k!=NULL)k = k->next;}if(k==NULL){q->next = p;}mid->next = q;}p = head;q = mid->next;while(q!=NULL){mid->next = q->next;q->next = p->next;p->next = q;p = p->next->next;q = mid->next;} }};
class Solution {public: void reorderList(ListNode *head) { if(head == NULL || head->next == NULL || head->next->next == NULL)return ;ListNode *mid,*p,*q,*pre=NULL;mid=p=q=head;while(p!=NULL && p->next!=NULL){p = p->next->next;mid = mid->next;}p = mid->next;if(p->next!=NULL){while(p!=NULL){q = p->next;p->next = pre;pre = p;p = q;}mid->next = pre;}p = head;q = mid->next;while(q!=NULL){mid->next = q->next;q->next = p->next;p->next = q;p = p->next->next;q = mid->next;} }};
Rotate List
Given a list, rotate the list to the right by k places, where k is non-negative.
For example:
Given 1->2->3->4->5->NULL
and k = 2
,
return 4->5->1->2->3->NULL
.
class Solution {public: ListNode *rotateRight(ListNode *head, int k) { //完全理解错题目的意思,不是找到倒数第k个旋转就好的,此处考虑k是否大于等于链表长度 //而是不断将链表右边的节点向左边旋转k次,k可以无限大,但是可以转化成前面的问题//规律在于,其实k<length就是前面一个问题,k>length取k % length的值必定小于length即使前面的问题,k==length就是一样的链表 //小心可能k的值比链表长度要大,可能一样长度if(head == NULL || head->next == NULL || k==0)return head;ListNode *p, *q,*next;next=p=q=head;int c = 1;while(p->next!=NULL)//计算链表长度{p = p->next;++c;}k = k % c;if(k==0)return head;p = head;c = 0;while(p!=NULL)//p多走k步{p = p->next;++ c;if(c == k)break;}while(p->next!=NULL)//p,q同时走,最后q到达的就是倒数第k个节点的前一个节点,因为我对p->next进行判断,p走到最后一个NULL节点的前一个有 //效节点{q = q->next;p = p->next;}next = q->next;//第k个节点q->next = NULL;//倒数第K个节点的前一个节点处断开,p->next = head;return next; }};
Partition List
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
//虽然正确率很高,但是我做了蛮久一是效率低下,一是,太多情况要考虑,有点乱 //首先可能都大于x,或者都小于等于x,还有就是有大于等于也有小于的 //next = cur->next;class Solution {public: ListNode *partition(ListNode *head, int x) { if(head == NULL || head->next == NULL)return head;ListNode* guard = new ListNode(0);guard->next = head;ListNode *cur, *next,*pre;cur = next = guard;//找到第一个大小的分割点,curif(cur->next->val < x)//首先找到大于等于x的节点的前一个节点,如果第一个就小于x往下找直到到第一个大于等于的节点,如果第一个就大于,不 处理{while(cur->next!= NULL && cur->next->val < x)cur = cur->next;} pre = cur;next = cur->next;while(next != NULL)//如果是都小于则退出{if(next->val >= x)//如果都小于等于也退出了,或者是都是大于等于的也退出了,否则,next指向第一个小于的节点,cur是前面小于的最后一个 节点,或者是第一个是大于的前一个guard节点,pre是next的父亲节点{while(next!= NULL && next->val >= x){ pre = next; next = next->next;}}if(next!=NULL)//加NULL判断,是哪种原因推出while的,{//链接 pre->next = next->next; next->next = cur->next; cur->next = next; cur = cur->next;//注意cur是前面小于的最后一个 节点,需要往后移动一个 next = pre->next;//next此时是pre的下一个节点}}return guard->next; }};
class Solution {public: ListNode *partition(ListNode *head, int x) { if(head == NULL || head->next == NULL) return head; ListNode* left = new ListNode(-1); ListNode* right = new ListNode(-1); ListNode* l_h = left; ListNode* r_h = right; ListNode* cur = head; while(cur!=NULL) { if(cur->val < x) { l_h->next = cur; l_h = l_h->next; } else { r_h->next = cur; r_h = r_h->next; } cur = cur->next; } l_h->next = right->next; r_h->next = NULL; return left->next; }};
Copy List with Random Pointer
class Solution {public: void CloneNodes(RandomListNode* head) { RandomListNode* h = head; while(h != NULL) { RandomListNode* p1 = new RandomListNode(h->label); p1->next = h->next; h->next = p1; h = p1->next; } } void ConnectRandomLinks(RandomListNode *head) { RandomListNode* h = head; while(h!=NULL) { RandomListNode* p = h->next; if(h->random != NULL)p->random = h->random->next; h = p->next; } } RandomListNode *ReconnectNodes(RandomListNode *head) { RandomListNode* h = head; RandomListNode* clonedHead = NULL; RandomListNode* clonedNode = NULL; if(h != NULL) { clonedHead = clonedNode = h->next; h->next = clonedNode->next; h = h->next; } while(h!=NULL) { clonedNode->next = h->next; clonedNode = clonedNode->next; h->next = clonedNode->next; h = h->next; } return clonedHead; }RandomListNode *copyRandomList(RandomListNode *head) { if(head == NULL ) return head; CloneNodes(head); ConnectRandomLinks(head); return ReconnectNodes(head);}};
- cycle,reverse,rotate linked list
- Two pointers (1) -- Linked List Cycle II, Rotate List
- leetcode Linked List Cycle & Linked List Cycle ||
- Linked List Cycle II Linked List Cycle
- 【LeetCode】Linked List Cycle
- Leetcode: Linked List Cycle
- Leetcode Linked List Cycle
- Linked List Cycle
- Linked List Cycle II
- Linked List Cycle
- Linked List Cycle
- Linked List Cycle II
- Leetcode: Linked List Cycle
- LeetCode:Linked List Cycle
- Linked List Cycle II
- Linked List Cycle
- Linked List Cycle II
- [LeetCode]Linked List Cycle
- FPGA机器学习之龙星计划机器学习第一堂
- 骨骼和Blendshape的区别
- 初探unix核心
- WinDbg 命令集锦
- 4.一个球从100m高度自由落下,每次落地后反跳回原来高度的一半,再落下,再反弹。求它在第10次落地时,共经过多少米?第10次反弹多高。
- cycle,reverse,rotate linked list
- Poj 3692 Kindergarten 二分图最大独立点集
- UVA 10888 km 题库61页
- (韩顺平讲解)pl/sql编程(一)
- jsp中找不到jquery.js文件解决办法
- 1833. The Hardest Problem Ever
- 更改谷歌浏览器缓存位置的方法
- 【Android】 - CentOS6.5 系统搭建 Android 开发环境
- 人工智能的复杂分析系统·