14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ““。

示例 1:

输入: ["flower","flow","flight"]
输出: "fl"

示例 2:

输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。

说明:

所有输入只包含小写字母 a-z 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
char * longestCommonPrefix(char ** strs, int strsSize){
    if(!strs || strsSize == 0){
        return "";
    }else if(strsSize == 1){
        return strs[0];
    }
    
    int idx = 0;
    const char *pbase = strs[0], *pcur = NULL;
    while(true){
        for(int i = 1; i < strsSize; i++){
            pcur = strs[i];
            if(!*(pbase + idx) || !*(pcur + idx) || 
                *(pbase + idx) != *(pcur + idx)){
                goto END;
            }
        }
        idx++;
    }
    
END:
    if(idx == 0){
        return "";
    }
    char * pret = (char *)malloc(sizeof(char)*idx+1);
    strncpy(pret, pbase, idx);
    pret[idx] = '\0';
    return pret;
}

测试一下,

执行结果:
通过
显示详情
执行用时 :8 ms, 在所有 C 提交中击败了69.44% 的用户
内存消耗 :7 MB, 在所有 C 提交中击败了82.49%的用户

344. 反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

示例 1:

输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:

输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void reverseString(char* s, int sSize){
    if(!s || sSize <= 1){
        return;
    }
    
    char *pbeg = s, *pend = s + sSize - 1;
    char tmp;
    while(pbeg < pend){
        tmp = *pbeg;
        *pbeg = *pend;
        *pend = tmp;
        pbeg++;
        pend--;
    }
    
    return;
}

测试一下,

执行结果:
通过
显示详情
执行用时 :64 ms, 在所有 C 提交中击败了97.30% 的用户
内存消耗 :13.7 MB, 在所有 C 提交中击败了75.23%的用户

415. 字符串相加

给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。

注意: num1 和num2 的长度都小于 5100. num1 和num2 都只包含数字 0-9. num1 和num2 都不包含任何前导零。 你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
void reverseString(char* s, int sSize){
    if(!s || sSize <= 1){
        return;
    }
    
    char *pbeg = s, *pend = s + sSize - 1;
    char tmp;
    while(pbeg < pend){
        tmp = *pbeg;
        *pbeg = *pend;
        *pend = tmp;
        pbeg++;
        pend--;
    }
    
    return;
}

int max(int a, int b){
    return a >= b ? a : b;
}

char * addStrings(char * num1, char * num2){
    int res_len = max(strlen(num1), strlen(num2)) + 2;
    char *res = (char *)calloc(sizeof(char), res_len);
    char *cur = res;
    int carry = 0, n1, n2, n3 = 0;
    reverseString(num1, strlen(num1));
    reverseString(num2, strlen(num2));
    while(*num1 || *num2){
        n1 = *num1 ? *num1 - '0' : 0;
        n2 = *num2 ? *num2 - '0' : 0;
        *cur = (n1 + n2 + carry)%10 + '0';
        carry = (n1 + n2 + carry)/10;
        if(*num1){num1++;}
        if(*num2){num2++;}
        cur++;
    }
    if(carry > 0){
        *cur = carry + '0';
        cur++;
    }
    reverseString(res, strlen(res));
    return res;
}

测试一下,

执行结果:
通过
显示详情
执行用时 :0 ms, 在所有 C 提交中击败了100.00% 的用户
内存消耗 :7 MB, 在所有 C 提交中击败了95.31%的用户

147. 对链表进行插入排序

对链表进行插入排序。

插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。 每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。

插入排序算法:

插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* insertionSortList(struct ListNode* head){
    if(!head || !head->next){
        return head;
    }
    
    struct ListNode dummy = {INT_MIN, head};
    struct ListNode *pre = NULL, *cur = head->next, *nxt = NULL;
    head->next = NULL;
    while(cur){
        nxt = cur->next;
        pre = &dummy;
        //find a pos for insert
        while(pre->next && pre->next->val < cur->val){
            pre = pre->next;
        }
        if(pre->next){
            cur->next = pre->next; //insert
        }else{
            cur->next = NULL; //append
        }
        pre->next = cur;
        cur = nxt;
    }
    
    return dummy.next;
}

测试一下,

执行结果:
通过
显示详情
执行用时 :52 ms, 在所有 C 提交中击败了64.36% 的用户
内存消耗 :8.1 MB, 在所有 C 提交中击败了36.96%的用户

148. 排序链表

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

输入: 4->2->1->3
输出: 1->2->3->4

示例 2:

输入: -1->5->3->4->0
输出: -1->0->3->4->5

代码与上题相同, 测试一下,

执行结果:
通过
显示详情
执行用时 :1008 ms, 在所有 C 提交中击败了15.38% 的用户
内存消耗 :9.9 MB, 在所有 C 提交中击败了96.67%的用户

709. 转换成小写字母

实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。

示例 1:

输入: "Hello"
输出: "hello"

示例 2:

输入: "here"
输出: "here"

示例 3:

输入: "LOVELY"
输出: "lovely"
1
2
3
4
5
6
7
8
9
10
11
12
13
char * toLowerCase(char * str){
    if(!str || !*str){
        return str;
    }
    char *ret = str;
    while(*str){
        if(*str >= 'A' && *str <= 'Z'){
            *str -= 'A' - 'a';
        }
        str++;
    }
    return ret;
}

测试一下,

执行结果:
通过
显示详情
执行用时 :4 ms, 在所有 C 提交中击败了83.76% 的用户
内存消耗 :6.8 MB, 在所有 C 提交中击败了5.57%的用户

557. 反转字符串中的单词 III

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例 1:

输入: "Let's take LeetCode contest"
输出: "s'teL ekat edoCteeL tsetnoc" 

注意:在字符串中,每个单词由单个空格分隔,并且字符串中不会有任何额外的空格。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
char * reverseWords(char * s){
    if(!s || !*s){
        return s;
    }
    
    char *beg = NULL, *end = NULL, *cur = s;
    char tmp;
    while(*cur){
        beg = cur;
        //find the head of a word
        while(*beg && isspace(*beg)){
            beg++;
        }
        
        //find the tail of a word
        end = beg;
        while(*end && !isspace(*end)){
            end++;
        }
        end--;
        
        //reverse the word
        cur = end + 1;
        while(beg < end){
            tmp = *beg;
            *beg = *end;
            *end = tmp;
            beg++;
            end--;
        }
    }
    
    return s;
}

测试一下,

执行结果:
通过
显示详情
执行用时 :12 ms, 在所有 C 提交中击败了86.12% 的用户
内存消耗 :8.3 MB, 在所有 C 提交中击败了42.16%的用户