出题:反转链表(递归和非递归解法);
分析:有递归跟非递归实现,注意对原始链表头节点的处理,因为其他节点都指向下一个节点,其需要指向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 }
时间: 2024-11-09 00:53:47