面试算法题:乾坤大挪移(链表旋转K个位置)
2014-02-24 16:53
260 查看
题目:
给定一个单向链表,设计一个算法实现链表向右旋转K个位置。K是非负的整数。
举例:
给定:1->2->3->4->5->6->null 并且 K=3;
则有:4->5->6->1->2->3->null。
分析:
这道题看上去简单,但是能耐做到bug free还是需要仔细思考的。
思考一些细节:
1.当K=0,怎么办?
2.当K等于链表长度时,怎么办?
3.当K大于链表长度时,怎么办?
算法设计:
除了K=0,显然,我们需要知道尾指针。那么,第一步,扫描链表得到尾指针tail和链表的长度M。如果M=0,完毕。第二步,设置两个指针p和q,同时指向第一个结点,然后q先走M-(K%M)-1步,然后p和q指针一起走,直到q指到终点,这个时候:
1)p->next所指向的节点为链表的第一个结点,设置头指针head->next = p->next;
2)将p所指节点的next指针指向null;
3)将q所指的结点的next指针指向旧的头结点。
代码:
结果:
K=0:
K=2:
K=3:
K=4:
再来看一个类似的题目:
对于有n个元素的数组int a
={....};写一个搞笑算法将数组内容循环左移m位。比如:char arr[] = "ABCDEFG",循环左移3位得到结果"DEFGABC"。
现在提供一个时间复杂度为O(n)的算法。
1)将arr[0]arr[1]...arr[m-1]所有元素逆置;
2)将arr[m]arr[m+1]..arr[strlen(arr)-1]所有元素逆置;
3)将arr整体逆置。
代码:
注明出处:http://blog.csdn.net/lavorange/article/details/19828095
给定一个单向链表,设计一个算法实现链表向右旋转K个位置。K是非负的整数。
举例:
给定:1->2->3->4->5->6->null 并且 K=3;
则有:4->5->6->1->2->3->null。
分析:
这道题看上去简单,但是能耐做到bug free还是需要仔细思考的。
思考一些细节:
1.当K=0,怎么办?
2.当K等于链表长度时,怎么办?
3.当K大于链表长度时,怎么办?
算法设计:
除了K=0,显然,我们需要知道尾指针。那么,第一步,扫描链表得到尾指针tail和链表的长度M。如果M=0,完毕。第二步,设置两个指针p和q,同时指向第一个结点,然后q先走M-(K%M)-1步,然后p和q指针一起走,直到q指到终点,这个时候:
1)p->next所指向的节点为链表的第一个结点,设置头指针head->next = p->next;
2)将p所指节点的next指针指向null;
3)将q所指的结点的next指针指向旧的头结点。
代码:
#include<iostream> #include<stdio.h> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; typedef int tData; typedef struct LNode { tData data; struct LNode *next; }tLNode; tLNode *head; void add(tData data); void create_list(tData *arr , int len) { head = new tLNode(); head->next = NULL; for(int i=0;i<len;i++) { add(arr[i]); } } void add(tData data) { tLNode *s = new tLNode(); s->data = data; s->next = NULL; tLNode *p = head; while(p->next!=NULL) { p = p->next; } p->next = s; } void display() { tLNode *p = head->next; while(p!=NULL) { cout<<"->"<<p->data; p = p->next; } cout<<endl; } void rotate_k(int k) { if(k==0) return ; tLNode *tail = head; int len = 0; while(tail->next!=NULL) { tail = tail->next; len++; } cout<<"the len = "<<len<<endl; tLNode *p = head->next; tLNode *q = p; int step = len - k%len - 1; for(int i=0;i<step;i++) { q = q->next; } head->next = q->next; q->next = NULL; tail->next = p; } int main() { tData array[] = {1,2,3,4,5,6,7,8,9} ; // *array ? int len = sizeof(array)/sizeof(array[0]); create_list(array,len); cout<<"input the k : "; int k; cin>>k; display(); rotate_k(k); display(); system("pause"); return 0; }
结果:
K=0:
K=2:
K=3:
K=4:
再来看一个类似的题目:
对于有n个元素的数组int a
={....};写一个搞笑算法将数组内容循环左移m位。比如:char arr[] = "ABCDEFG",循环左移3位得到结果"DEFGABC"。
现在提供一个时间复杂度为O(n)的算法。
1)将arr[0]arr[1]...arr[m-1]所有元素逆置;
2)将arr[m]arr[m+1]..arr[strlen(arr)-1]所有元素逆置;
3)将arr整体逆置。
代码:
#include<iostream> using namespace std; typedef char tData; void rotate(tData *start , tData *end ) { tData tmp; while(start<end) { tmp = *start; *start = *end; *end = tmp; start++; end--; } } int main() { tData arr[] = "ABCDEFG"; int k , len = strlen(arr); cout<<"please input the k : "; cin>>k; k = k%len; rotate(arr,arr+k-1); rotate(arr+k,arr+len-1); rotate(arr,arr+len-1); cout<<arr<<endl; system("pause"); return 0; }
注明出处:http://blog.csdn.net/lavorange/article/details/19828095
相关文章推荐
- C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- 【LeetCode-面试算法经典-Java实现】【025-Reverse Nodes in k-Group(单链表中k个结点一组进行反转)】
- C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- 链表系列-把链表向右旋转k个位置LeetCode#61. Rotate List
- 【LeetCode-面试算法经典-Java实现】【061-Rotate List(旋转单链表)】
- leetcode:Merge k Sorted Lists(按大小顺序连接k个链表)【面试算法题】
- 转:C/C++面试之算法系列--怎样快速检测出一个巨大的单链表中是否具备死链及其位置
- leetcode:Reorder List (修改链表排列不改变值) 【面试算法题】
- leetcode:Reverse Linked List II (反转链表中的一部分)【面试算法题】
- 【LeetCode-面试算法经典-Java实现】【023-Merge k Sorted Lists(合并k个排好的的单链表)】
- 面试算法(十六)合并两个排序的链表
- 面试算法(三十七)两个链表的第一个公共结点
- 【LeetCode-面试算法经典-Java实现】【082-Remove Duplicates from Sorted List II(排序链表中删除重复元素II)】
- 微软等数据结构+算法面试100题(40)-- 旋转数组中的最小元素
- [面试] 算法(六)—— 链表
- 算法面试题 - 找出两个单向链表相交的位置
- 人人都来写算法 之 在旋转数组中查找值并返回该值在数组中的位置
- 面试 7:快慢指针法玩转链表算法面试(一)
- leetcode:Remove Duplicates from Sorted List(去除链表中重复元素)【面试算法题】
- 面试算法之链表操作集锦