力扣(LeetCode)刷题,简单+中等题(第26期)

目录

第1题:字典序排数

第2题:字符串解码

第3题:查找常用字符

第4题:所有奇数长度子数组的和

第5题:长按键入

第6题:分割字符串的最大得分

第7题:回文链表

第8题:有多少小于当前数字的数字

第9题:两个相同字符之间的最长子字符串

第10题:分式化简


力扣(LeetCode)定期刷题,每期10道题,业务繁重的同志可以看看我分享的思路,不是最高效解决方案,只求互相提升。

中等题,可太吃力了,我觉得刷题C语言费劲。

第1题:字典序排数

试题要求如下:

解题思路:

字典或词典顺序(也称为词汇顺序,字典顺序,字母顺序或词典顺序)是基于字母顺序排列的单词按字母顺序排列的方法。

回答(C语言):


  
  1. /**
  2. * Note: The returned array must be malloced, assume caller calls free().
  3. */
  4. #define MY_MAX 20
  5. char g_sa[MY_MAX];
  6. char g_sb[MY_MAX];
  7. int cmp(const void *a, const void *b)
  8. {
  9. int *pa = (int*)a;
  10. int *pb = (int*)b;
  11. sprintf(g_sa, "%d", *pa);
  12. sprintf(g_sb, "%d", *pb);
  13. return strcmp(g_sa, g_sb);
  14. }
  15. int* proc(int n, int* returnSize){
  16. int i;
  17. int *rlt = (int*)calloc(n, sizeof(int));
  18. if (rlt == NULL) {
  19. return NULL;
  20. }
  21. for (i = 0; i < n; i++) {
  22. rlt[i] = i + 1;
  23. }
  24. qsort(rlt, n, sizeof(int), cmp);
  25. *returnSize = n;
  26. return rlt;
  27. }
  28. int* lexicalOrder(int n, int* returnSize){
  29. if (n <= 0) {
  30. returnSize = 0;
  31. return NULL;
  32. }
  33. return proc(n, returnSize);
  34. }

运行效率如下所示:


第2题:字符串解码

试题要求如下:

解题思路:

从右向左扫描,发现符合条件的,就替换,然后继续从右向左扫描,直到没有[]需要替换为止。

回答(C语言):


  
  1. char *decodeString(char *s)
  2. {
  3. if (s == NULL) {
  4. return NULL;
  5. }
  6. char *a = strdup(s);
  7. while (true) {
  8. int len = strlen(a);
  9. int left = 0, right = len;
  10. int i = len - 1, num = 0, w = 1;
  11. for (; i >= 0; i--) {
  12. if (a[i] == ']') {
  13. right = i;
  14. } else if(a[i] == '[') {
  15. left = i;
  16. } else if (a[i] >= '0' && a[i] <= '9') {
  17. do { // 组合数字
  18. num += w * (a[i] - '0');
  19. w *= 10;
  20. i--;
  21. } while (i >= 0 && (a[i] >= '0' && a[i] <= '9'));
  22. break;
  23. }
  24. }
  25. if (num == 0) { //没有[]了
  26. return a;
  27. } else {
  28. int slen = (right - left - 1);
  29. int count = (i + 1) + (len - right - 1) + num * slen + 1;
  30. char *t = (char*)calloc(count, sizeof(char));
  31. if (i + 1 > 0) { // 左
  32. memcpy(t, a, i + 1);
  33. }
  34. for (int k = 0; k < num; k++) { // 中
  35. memcpy(t + (i + 1) + k * slen, a + left + 1, slen);
  36. }
  37. if (len - right - 1 > 0) {
  38. memcpy(t + (i + 1) + num * slen, a + right + 1, len - right - 1);
  39. }
  40. free(a);
  41. a = t;
  42. }
  43. }
  44. }

运行效率如下所示:


第3题:查找常用字符

试题要求如下:

解题思路:

遍历所有的字符串,记录(26个小写字母)每个字符在所有字符串中都出现过的“最小”次数,则为结果。

回答(C语言):


  
  1. /**
  2. * Note: The returned array must be malloced, assume caller calls free().
  3. */
  4. char ** commonChars(char ** A, int ASize, int* returnSize){
  5. if (NULL == A || 0 == ASize)
  6. {
  7. *returnSize = 0;
  8. return NULL;
  9. }
  10. int minfreq[26]; // 记录每个‘字符’出现的最小频率
  11. int freq[26]; // 缓存每个字符串中每个’字符‘出现的频率
  12. for (int i = 0; i < 26; i++)
  13. {
  14. minfreq[i] = INT_MAX;
  15. }
  16. // 遍历所有字符串
  17. for (int i = 0; i < ASize; i++)
  18. {
  19. // 遍历每个字符串前,重置’字符‘出现的频率
  20. memset(freq, 0, sizeof(freq));
  21. int n = strlen(A[i]); // 当前字符串长度
  22. // 遍历当前字符串
  23. for (int j = 0; j < n; j++)
  24. {
  25. int idx = A[i][j] - 'a'; // 字符的下标
  26. ++freq[idx]; // 统计’字符‘出现的次数
  27. }
  28. // 每遍历一个字符串,都需更新所有字符出现的最小频率
  29. for (int k = 0; k < 26; k++)
  30. {
  31. minfreq[k] = fmin(minfreq[k], freq[k]);
  32. }
  33. }
  34. // 计算结果字符
  35. int sum = 0;
  36. for (int i = 0; i < 26; i++)
  37. {
  38. sum += minfreq[i];
  39. }
  40. // 构造结果字符列表
  41. char** result = (char**)malloc(sizeof(char*) * sum);
  42. *returnSize = 0;
  43. for (int i = 0; i < 26; i++) // 遍历 26 个小写字符
  44. {
  45. for (int j = 0; j < minfreq[i]; j++) // 遍历每个‘字符’在所有字符串中都出现的最小次数
  46. {
  47. result[*returnSize] = (char*)malloc(sizeof(char) * 2); // 每个字符串都有结束符,所以需 +1
  48. result[*returnSize][0] = i + 'a'; // 第 i 个字符
  49. result[*returnSize][1] = '\0'; // '\0' 作为字符串结束标识
  50. (*returnSize)++;
  51. }
  52. }
  53. return result;
  54. }

运行效率如下所示:


第4题:所有奇数长度子数组的和

试题要求如下:

回答(C语言):


  
  1. int sumOddLengthSubarrays(int* arr, int arrSize){
  2. int res = 0;
  3. for (int i = 0; i < arrSize; i++) {
  4. for (int j = 1; j < arrSize - i + 1; j += 2) {
  5. for (int m = i; m < i + j; m++) {
  6. res = res + arr[m];
  7. }
  8. }
  9. }
  10. return res;
  11. }

运行效率如下所示:


第5题:长按键入

试题要求如下:

回答(C语言):


  
  1. bool isLongPressedName(char* name, char* typed) {
  2. int n = strlen(name), m = strlen(typed);
  3. int i = 0, j = 0;
  4. while (j < m) {
  5. if (i < n && name[i] == typed[j]) {
  6. i++;
  7. j++;
  8. } else if (j > 0 && typed[j] == typed[j - 1]) {
  9. j++;
  10. } else {
  11. return false;
  12. }
  13. }
  14. return i == n;
  15. }

运行效率如下所示:


第6题:分割字符串的最大得分

试题要求如下:

回答(C语言):


  
  1. int max(int x,int y){
  2. return x>y?x:y;
  3. }
  4. int maxScore(char * s){
  5. int l=strlen(s);
  6. int lsum=0;
  7. int rsum=0;
  8. int maxN=0;
  9. for(int i=0;i<l-1;i++){
  10. if(s[i]=='0')
  11. lsum++;
  12. for(int j=i+1;j<l;j++){
  13. if(s[j]=='1'){
  14. rsum++;
  15. }
  16. }
  17. maxN=max(maxN,lsum+rsum);
  18. rsum=0;
  19. }
  20. return maxN;
  21. }

运行效率如下所示:


第7题:回文链表

试题要求如下:

解答思路:

1、复制链表值到数组列表中;

2、使用双指针法判断是否为回文。

回答(C语言):


  
  1. /**
  2. * Definition for singly-linked list.
  3. * struct ListNode {
  4. * int val;
  5. * struct ListNode *next;
  6. * };
  7. */
  8. bool isPalindrome(struct ListNode* head) {
  9. int vals[50001], vals_num = 0;
  10. while (head != NULL) {
  11. vals[vals_num++] = head->val;
  12. head = head->next;
  13. }
  14. for (int i = 0, j = vals_num - 1; i < j; ++i, --j) {
  15. if (vals[i] != vals[j]) {
  16. return false;
  17. }
  18. }
  19. return true;
  20. }

运行效率如下所示:


第8题:有多少小于当前数字的数字

试题要求如下:

回答(C语言):


  
  1. /**
  2. * Note: The returned array must be malloced, assume caller calls free().
  3. */
  4. int* smallerNumbersThanCurrent(int* nums, int numsSize, int* returnSize) {
  5. int* ret = malloc(sizeof(int) * numsSize);
  6. *returnSize = numsSize;
  7. for (int i = 0; i < numsSize; i++) {
  8. int cnt = 0;
  9. for (int j = 0; j < numsSize; j++) {
  10. if (nums[j] < nums[i]) {
  11. cnt++;
  12. }
  13. }
  14. ret[i] = cnt;
  15. }
  16. return ret;
  17. }

运行效率如下所示:


第9题:两个相同字符之间的最长子字符串

试题要求如下:

解题思路:

1、初始化哈希表,定义max = -1;

2、如果当前字符第一次出现,记下当前下标i;

3、如果字符已经出现过,利用当前下标i减去表中的记录值tmp,判断如果max小于tmp,则更新max,否则不更新;

4、释放缓冲区hash。

回答(C语言):


  
  1. #define Max( a , b ) ( ( a > b ) * a + ( a <= b ) * b )
  2. int maxLengthBetweenEqualCharacters( char * s ){
  3. //creating hash table
  4. int * hash = ( int * )malloc( sizeof( int ) * 26 );
  5. int max = -1;
  6. //intializing hash table
  7. for( int i = 0 ; i < 26 ; i++ ) {
  8. hash[ i ] = -1;
  9. }
  10. for( int i = 0 ; s[ i ] != '\0' ; i++ ) {
  11. if( hash[ s[ i ] - 97 ] != -1 ) {
  12. max = Max( max , ( i - hash[ s[ i ] - 97 ] - 1 ) );
  13. } else {
  14. hash[ s[ i ] - 97 ] = i;
  15. }
  16. }
  17. free( hash );
  18. return max;
  19. }

运行效率如下所示:


第10题:分式化简

试题要求如下:

解题思路:

回答(C语言):


  
  1. /**
  2. * arr[0]: 分子
  3. * arr[1]: 分母
  4. *
  5. * 1、简单的通分,因为每次都是 1/a,所以需要分数翻转,即分子分母交换一下
  6. * 2、这题不需要约分,本来就是最简
  7. */
  8. int* fraction(int* cont, int contSize, int* returnSize) {
  9. int* arr = (int*)malloc(sizeof(int) * 2);
  10. arr[0] = 1;
  11. arr[1] = 0;
  12. for (int i = contSize - 1; i >= 0; i--) {
  13. int temp = arr[1];
  14. arr[1] = arr[0];
  15. arr[0] = cont[i] * arr[1] + temp;
  16. }
  17. *returnSize = 2;
  18. return arr;
  19. }

运行效率如下所示:

 

文章来源: handsome-man.blog.csdn.net,作者:不脱发的程序猿,版权归原作者所有,如需转载,请联系作者。

原文链接:handsome-man.blog.csdn.net/article/details/109325598

(完)