出题:反转链表(递归和非递归解法);
分析:有递归跟非递归实现,注意对原始链表头节点的处理,因为其他节点都指向下一个节点,其需要指向NULL;
解题:
struct Node {
int v;
Node *next;
};
Node* NonRecursiveListReverse(Node *head) {
if(head == NULL) return NULL;
Node *previous=NULL, *current=head, *temp=NULL;
/**
* 一定需要注意删除原来的结构,不然最后一个指针与倒数第二个指针
* 相互索引,最终导致无限循环索引
* */
//previous->next=NULL; while(current != NULL) {
temp=current->next;
current->next=previous; previous=current;
current=temp;
} return previous;
}
/**
* 调用此方法的时候需要将previous设置成NULL,也就是
* RecursiveListReverse(NULL, head);
* */
Node* RecursiveListReverse(Node *previous, Node *current) {
Node *temp=current->next;
current->next=previous;
if(temp == NULL) return current;
else return RecursiveListReverse(current, temp);
}
出题:左旋转字符串算法,将字符串最左边的k个字符移动到字符串尾部,局部字符相对顺序不变。要求时间复杂度为O(N),空间复杂度为O(1);
分析:例如:对"abcdef"施用k=3的左旋转之后变成"cdefabc"。本题与19类似,首先进行全局反转,然后利用k的长度分别对两个部分进行反转;
解题:
/**
* 借用之前已经实现的全局翻转函数reverse
* */
void reverse(char* target, int length) {
char temp;
int i;
for(i=;i<length/;i++) {
temp=*(target+i);
*(target+i)=*(target+(length-i-));
*(target+(length-i-))=temp;
}
} void LeftRotate(char *target, int length, int k) {
reverse(target,length);
reverse(target, length-k);
reverse(target+length-k, k);
}
int main() {
char target[]="abcdef";
LeftRotate(target, , );
char *temp=target;
printf("\n%s\n", temp);
return ;
}