5.最長迴文子串(LeetCode)——C語言

1、暴力破解

#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// 判斷字符串是不是迴文字符串
int isPalindromic(char *str, int start, int end)
{
  while (start < end)
  {
    if (str[start] != str[end])
    {
      return false;
    }
    start++;
    end--;
  }
  return true;
}

char *longestPalindrome(char *str)
{
  int len = strlen(str);
  int k = 0;
  if (len < 2)
  {
    return str;
  }
  // 迴文字符串最小長度爲1,由於任何一個字符從左往右和從右往左讀都是迴文的
  // 所以長度爲1的子串是迴文的,默認返回第一個字符
  int maxLen = 1, startIndex = 0;
  // 遍歷全部長度>=2的子串,若是沒有,則使用上面的默認值,即
  // 返回長度爲1的子串,而且是字符串第一個字符
  for (int i = 0; i < len - 1; i++)
  {
    for (int j = i + 1; j < len; j++)
    {
      // 當新的子串長度大於maxLen時,再判斷是否迴文
      // 若是迴文,則更新maxLen,同時更新startIndex
      if (j - i + 1 > maxLen && isPalindromic(str, i, j))
      {
        maxLen = j - i + 1;
        startIndex = i;
      }
    }
  }
  // 下面這兩行代碼這樣能夠將空間複雜度降到O(1)
  // str[startIndex + maxLen] = '\0';
  // return str + startIndex;
  
  // 分配存儲空間,存儲新字符串並返回
  // 分配的時候要多分配一個空間用來存儲空字符'\0'
  char *palindromic = (char *)malloc((maxLen + 1) * sizeof(char));
  for (int i = 0; i < maxLen; i++)
  {
    palindromic[i] = str[startIndex + i];
  }
  palindromic[maxLen] = '\0';
  return palindromic;
}
int main(void)
{
  int i = 0;
  char str[] = "babad";
  char *palind = NULL;
  palind = longestPalindrome(str);
  while (palind[i] != '\0')
  {
    printf("%c", palind[i]);
    i++;
  }
}
執行用時:304 ms, 在全部 C 提交中擊敗了26.13%的用戶
內存消耗:5.9 MB, 在全部 C 提交中擊敗了79.53%的用戶
時間複雜度O(n^3),空間複雜度O(n)。
這種方法只會返回一種解,便可能有多個最長迴文串,此方法只返回最早遍歷到的。

中心擴散法

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 中心擴散法
int expandCenter(char *str, int left, int right, int len)
{
  // 若是長度是奇數,則中心只有一個,left和right傳相同的值
  // 若是長度是偶數,則中心是兩個數,left和right相差1
  while (left >= 0 && right < len)
  {
    if (str[left] == str[right])
    {
      left--;
      right++;
    }
    else
    {
      break;
    }
  }
  return right - left - 1;
}

char *longestPalindrome(char *str)
{
  int len = strlen(str);
  if (len < 2)
  {
    return str;
  }
  int maxLen = 1;
  int startIndex = 0;
  for (int i = 0; i < len; i++)
  {
    // 當迴文串長度爲奇數時調用
    int odd = expandCenter(str, i, i, len);
    // 當迴文串長度爲偶數時調用
    int even = expandCenter(str, i, i + 1, len);
    // 將最長的賦值給maxLen
    int newMaxLen = odd > even ? odd : even;
    if (newMaxLen > maxLen)
    {
      maxLen = newMaxLen;
      startIndex = i - (maxLen - 1) / 2;
    }
  }
  
  // 下面這兩行代碼這樣能夠將空間複雜度降到O(1)
  // str[startIndex + maxLen] = '\0';
  // return str + startIndex;
  char *palindromic = (char *)malloc((maxLen + 1) * sizeof(char));
  for (int i = 0; i < maxLen; i++) {
    palindromic[i] = str[i + startIndex];
  }
  palindromic[maxLen] = '\0';
  return palindromic;
}

int main(void)
{
  char str[] = "abcdefghgfedklmn";
  char *palind = longestPalindrome(str);
  int i = 0;
  while (palind[i] != '\0') {
    printf("%c", palind[i]);
    i++;
  }
}
執行用時:20 ms, 在全部 C 提交中擊敗了80.27%的用戶 內存消耗:6 MB, 在全部 C 提交中擊敗了68.40%的用戶 時間複雜度O(n^2),空間複雜度O(n)。
相關文章
相關標籤/搜索