笔试算法题(13):反转链表 & 左旋转字符串

出题:反转链表(递归和非递归解法);

分析:有递归跟非递归实现,注意对原始链表头节点的处理,因为其他节点都指向下一个节点,其需要指向NULL;

解题:

 1 struct Node {
 2         int v;
 3         Node *next;
 4 };
 5 Node* NonRecursiveListReverse(Node *head) {
 6         if(head == NULL) return NULL;
 7         Node *previous=NULL, *current=head, *temp=NULL;
 8         /**
 9          * 一定需要注意删除原来的结构,不然最后一个指针与倒数第二个指针
10          * 相互索引,最终导致无限循环索引
11          * */
12         //previous->next=NULL;
13 
14         while(current != NULL) {
15                 temp=current->next;
16                 current->next=previous;
17 
18                 previous=current;
19                 current=temp;
20         }
21 
22         return previous;
23 }
24 /**
25  * 调用此方法的时候需要将previous设置成NULL,也就是
26  * RecursiveListReverse(NULL, head);
27  * */
28 Node* RecursiveListReverse(Node *previous, Node *current) {
29         Node *temp=current->next;
30         current->next=previous;
31         if(temp == NULL) return current;
32         else return RecursiveListReverse(current, temp);
33 }

 

出题:左旋转字符串算法,将字符串最左边的k个字符移动到字符串尾部,局部字符相对顺序不变。要求时间复杂度为O(N),空间复杂度为O(1);

分析:例如:对"abcdef"施用k=3的左旋转之后变成"cdefabc"。本题与19类似,首先进行全局反转,然后利用k的长度分别对两个部分进行反转;

解题:

 1 /**
 2  * 借用之前已经实现的全局翻转函数reverse
 3  * */
 4 void reverse(char* target, int length) {
 5         char temp;
 6         int i;
 7         for(i=0;i<length/2;i++) {
 8                 temp=*(target+i);
 9                 *(target+i)=*(target+(length-i-1));
10                 *(target+(length-i-1))=temp;
11         }
12 }
13 
14 void LeftRotate(char *target, int length, int k) {
15         reverse(target,length);
16         reverse(target, length-k);
17         reverse(target+length-k, k);
18 }
19 int main() {
20         char target[]="abcdef";
21         LeftRotate(target, 6, 3);
22         char *temp=target;
23         printf("\n%s\n", temp);
24         return 0;
25 }

 

posted @ 2014-05-20 10:24  Leo C.  阅读(338)  评论(0编辑  收藏  举报