【LeetCode每日一题】——1147.段式回文

文章目录

  • 一【题目类别】
  • 二【题目难度】
  • 三【题目编号】
  • 四【题目描述】
  • 五【题目示例】
  • 六【解题思路】
  • 七【题目提示】
  • 八【时间频度】
  • 九【代码实现】
  • 十【提交结果】

一【题目类别】

  • 双指针

二【题目难度】

  • 困难

三【题目编号】

  • 1147.段式回文

四【题目描述】

  • 你会得到一个字符串 t e x t text text 。你应该把它分成 k k k 个子字符串 ( s u b t e x t 1 subtext_1 subtext1, s u b t e x t 2 subtext_2 subtext2,…, s u b t e x t k subtext_k subtextk) ,要求满足:
    • s u b t e x t i subtext_i subtexti 是 非空 字符串
    • 所有子字符串的连接等于 t e x t text text ( 即 s u b t e x t 1 subtext_1 subtext1 + s u b t e x t 2 subtext_2 subtext2 + … + s u b t e x t k subtext_k subtextk == text )
    • s u b t e x t i subtext_i subtexti == s u b t e x t k − i + 1 subtext_{k - i + 1} subtextki+1 表示所有 i i i 的有效值( 即 1 < = i < = k 1 <= i <= k 1<=i<=k )
  • 返回 k k k可能最大值。

五【题目示例】

  • 示例 1:

    • 输入:text = “ghiabcdefhelloadamhelloabcdefghi”
    • 输出:7
    • 解释:我们可以把字符串拆分成 “(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)”。
  • 示例 2:

    • 输入:text = “merchant”
    • 输出:1
    • 解释:我们可以把字符串拆分成 “(merchant)”。
  • 示例 3:

    • 输入:text = “antaprezatepzapreanta”
    • 输出:11
    • 解释:我们可以把字符串拆分成 “(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)”。

六【解题思路】

  • 这道题首先要读懂题意,题目的意思就是判断是否是回文字符串,但是这个回文不是以字符为单位的,而是以分段的字符串为单位的
  • 但是整体思路都差不多,一个指针从左到右遍历,一个指针从右向左遍历
  • 从左向右遍历的指针要基于一个贪心的原则,也就是说每次遍历完后,下一次的位置,是加上最小相等段的长度
  • 从右向左遍历的指针是为了找到最小合法长度的段的起始位置,然后比较当前这个长度是否可以让两个字符串相等,如果相等,说明是一对合法段。如果不相等,继续找即可
  • 我们还要记录当前子段的长度,为了下次遍历的时候跳过这些元素
  • 其实整个算法就是一个基于贪心的思路,遇到一个就检测一下,不放过任何一个,在保证合法的前提下还保证了最短,既然保证了最短,就能让段的个数最多
  • 最后返回结果即可

七【题目提示】

  • 1 <= text.length <= 1000
  • text 仅由小写英文字符组成

八【时间频度】

  • 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n 是字符串的长度
  • 空间复杂度: O ( 1 ) O(1) O(1)

九【代码实现】

  1. Java语言版
package DoublePointer;

public class p1147_LongestChunkedPalindromeDecomposition {

    public static void main(String[] args) {
        String text = "ghiabcdefhelloadamhelloabcdefghi";
        int res = longestDecomposition(text);
        System.out.println("res = " + res);
    }

    public static int longestDecomposition(String text) {
        int len = text.length();
        int k = 0;
        int subLen = 1;
        for (int i = 0; i < len; i += subLen) {
            subLen = 1;
            for (int j = len - 1 - i; j >= 0; j--) {
                if ((text.charAt(i) == text.charAt(j)) && (compareStr(text, i, j, subLen) == 0)) {
                    k++;
                    break;
                }
                subLen++;
            }
        }
        return k;
    }

    public static int compareStr(String text, int i, int j, int len) {
        if ((j + len) > text.length()) {
            return -1;
        }
        int flag = 0;
        while (len-- != 0) {
            if (text.charAt(i) == text.charAt(j)) {
                i++;
                j++;
            } else {
                flag = -1;
            }
        }
        return flag;
    }

}
  1. C语言版
#include
#include

int compareStr(char* text, int i, int j, int len)
{
	if ((j + len) > strlen(text))
	{
		return -1;
	}
	return strncmp(&text[i], &text[j], len);
}

int longestDecomposition(char * text)
{
	int len = strlen(text);
	int k = 0;
	int subLen = 1;
	for (int i = 0; i < len; i += subLen)
	{
		subLen = 1;
		for (int j = len - 1 - i; j >= 0; j--)
		{
			if ((text[i] == text[j]) && (compareStr(text, i, j, subLen) == 0))
			{
				k++;
				break;
			}
			subLen++;
		}
	}
	return k;
}

/*主函数省略*/

十【提交结果】

  1. Java语言版
    【LeetCode每日一题】——1147.段式回文_第1张图片

  2. C语言版
    【LeetCode每日一题】——1147.段式回文_第2张图片

你可能感兴趣的:(LeetCode,leetcode,算法,数据结构,双指针,字符串)