LeetCode 151. Reverse Words in a String 很适合练习C语言基础,练习一个OJ题目除了找最佳解法,还可以多想想刻意去练习一些数据结构等其他知识点,举一反三。
Given an input string, reverse the string word by word.
Example:
Input: “the sky is blue”,
Output: “blue is sky the”.
Note:
A word is defined as a sequence of non-space characters.
Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces.
You need to reduce multiple spaces between two words to a single space in the reversed string.
解法一:练习字符串parse
size_t parse(const char *s, char *buf, size_t bufLen) {
size_t i = 0, j = 0, pos = bufLen - 1;
while (s[i] == ' ' && s[i] != '\0') i++;
j = i;
while (s[i] != '\0') {
while (s[j] != ' ' && s[j] != '\0') j++;
pos -= (j - i);
memcpy(&buf[pos], &s[i], j - i);
if (pos > 0) {
buf[--pos] = ' ';
}
while (s[j] == ' ' && s[j] != '\0') j++;
i = j;
}
return buf[pos] == ' ' ? pos + 1: pos;
}
void reverseWords(char *s) {
size_t len = strlen(s) + 1;
char *buf = malloc(len);
memset(buf, 0, len);
size_t pos = parse(s, buf, len);
strcpy(s, &buf[pos]);
free(buf);
}
解法二:练习链表的使用
struct WordList {
char *word;
struct WordList *next;
};
void insert(struct WordList **head, char *word) {
struct WordList *node = malloc(sizeof(struct WordList));
node->next = *head;
node->word = word;
*head = node;
}
void parse(const char *s, struct WordList **head) {
size_t i = 0, j = 0;
while (s[i] == ' ' && s[i] != '\0') i++;
j = i;
while (s[i] != '\0') {
while (s[j] != ' ' && s[j] != '\0') j++;
char *word = malloc(j - i + 1);
memcpy(word, &s[i], j - i);
word[j - i] = '\0';
insert(head, word);
while (s[j] == ' ' && s[j] != '\0') j++;
i = j;
}
}
void reverseWords(char *s) {
struct WordList *head = NULL;
parse(s, &head);
struct WordList *cur = head, *tmp;
s[0] = 0;
while (cur) {
strcat(s, cur->word);
if (cur->next) {
strcat(s, " ");
}
tmp = cur;
cur = cur->next;
free(tmp->word);
free(tmp);
}
}
对比
上面两种方法parse字符串部分是一样的,区别在于存储,重点练习链表的解法调用了多次malloc和free,性能自然是比不过用一个array来操作的。结果也是:第一种array解法,runtime击败了100%的提交;第二种用链表只击败了2%。题目本身如果用C++或Java等都有标准库,直接就可以搞定,但是就失去了练习的目的了,用C语言用多种思路来解,就可以很好地起到练习的作用。