小练习 - LeetCode151 Reverse Words in a String的C语言解法

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语言用多种思路来解,就可以很好地起到练习的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值