Leetcode | 连接两字母单词得到的最长回文串

简介: Leetcode | 连接两字母单词得到的最长回文串

Leetcode | 连接两字母单词得到的最长回文串

题目信息

image.png

我感觉我在用做业务的逻辑解题,逻辑通了,题就自然而然地解出来,不知道这样有没有问题。

首先要从题目中获取两个信息:

  1. 存在重复的字符串
  2. 需要注意aa型字符串(即第一个字符和第二个字符相同)

解题思路

1、把字符转成二维数组,并且标记数量

2、分类讨论存在回文字符串的情况

  1. 当不是aa型字符串时,最小的那个字符串的数量就是一半回文的长度
  2. 当是aa型字符串时,就要考虑奇数和偶数的问题
  3. 当是偶数时,可以形成回文,直接添加数量
  4. 当是奇数时,就要考虑这里面有多少个奇数的aa型字符串。再多的奇数字符串,只有一个能放到中间,形成回文。如:aa,aa,aa,bb,bb,bb,cc组成的字符串为aabbccbbaaaabbaabbaaaabbbbbbaa,也就是说奇数的aa,bb,cc只有一个能放在字符串的最中间位置。

示例代码

public class Solution {
    public int longestPalindrome(String[] words) {
        // 添加标记位,记录对应的字符串出现的次数
        int[][] one = new int[123][123];
        int n = words.length;
        // 字符串转标记数组,并且记录数量
        for (int i = 0; i < n; i++) {
            String str = words[i];
            char a = str.charAt(0);
            char b = str.charAt(1);
            // 记录相关位置的数量
            one[a][b] += 1;
        }
        // 最终的数量
        int ans = 0;
        // 记录是否存在aa类型的字符串,并且是奇数
        boolean flag = false;
        // 循环处理字符串
        for (int i = 0; i < n; i++) {
            String str = words[i];
            char a = str.charAt(0);
            char b = str.charAt(1);
            // 如果小于1表示反转的字符串不存在,或者已经计算过数量
            if (one[b][a] < 1)
                continue;
            // 如果不是aa型字符串,第一位字符和第二位字符不想等
            if (a != b) {
                // 数量是最少的那个字符串的数量,回文每次都是两个字符串,所以要乘上2
                ans += (Math.min(one[a][b], one[b][a]) << 1);
            } else if (a == b) {
                // 如果是aa型的字符串,则判断数量是奇数还是偶数
                int num = one[a][b];
                if (num % 2 == 1) {
                    // 当存在多个奇数的aa型字符串时,最后只有一个字符串能放到中间形成回文,如:aa,aa,aa,bb,bb,bb,cc,dd,dd组成的字符串为aabbccbbaa,aabbaabbaa
                    // 数量是奇数时,计算除以2的商,偶数的个数,可以形成回文
                    ans += ((num >> 1) << 1);
                    flag = true;
                } else {
                    // 偶数个的字符串,直接添加数量
                    ans += num;
                }
            }
            // 清除标记位,表示这个字符串已经计算过了
            one[a][b] = 0;
            one[b][a] = 0;
        }
        // 返回最终的数量,字符数量需要乘2
        return flag ? (1 + ans) * 2 : ans * 2;
    }
}
目录
相关文章
|
1月前
|
存储 算法
LeetCode第49题字母异位词分组
LeetCode第49题"字母异位词分组"的解题方法,通过将每个字符串的字符排序后作为键存储在HashMap中,有效地将所有字母异位词分组。
LeetCode第49题字母异位词分组
|
1月前
|
算法
LeetCode第58题最后一个单词的长度
LeetCode第58题"最后一个单词的长度"的解题方法,通过从字符串末尾向前遍历并计数非空格字符,直接得出最后一个单词的长度。
LeetCode第58题最后一个单词的长度
|
1月前
|
算法
LeetCode第17题电话号码的字母组合
该文章介绍了 LeetCode 第 17 题电话号码的字母组合的解法,通过分析得出可使用递归和回溯的思想解决,避免循环穷举的高循环次数,并给出了具体的编码实现,同时总结了该题较难理解,需要了解递归的本质,当嵌套循环层次多时可考虑递归。
LeetCode第17题电话号码的字母组合
|
1月前
|
算法 JavaScript Python
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
21 4
|
1月前
|
Python
【Leetcode刷题Python】生词本单词整理
文章提供了一个Python程序,用于帮助用户整理和排版生词本上的单词,包括去除重复单词、按字典序排序,并按照特定的格式要求进行打印排版。
21 3
|
1月前
|
Python
【Leetcode刷题Python】318. 最大单词长度乘积
本文提供了LeetCode题目318的Python编程解决方案,题目要求在一个字符串数组中找出两个不含有公共字母的单词,且这两个单词的长度乘积最大,如果不存在这样的两个单词,则返回0。
12 0
|
1月前
|
Python
【Leetcode刷题Python】234.回文链表
两种判断链表是否为回文的方法:使用栈和拆分为两个链表后反转对比,并给出了相应的Python代码实现。
15 0
|
3月前
|
存储
力扣经典150题第四十二题:字母异位词分组
力扣经典150题第四十二题:字母异位词分组
19 0
|
3月前
|
存储
力扣经典150题第四十一题:有效的字母异位词
力扣经典150题第四十一题:有效的字母异位词
18 0
|
3月前
|
算法 测试技术 索引
力扣经典150题第三十二题:串联所有单词的子串
力扣经典150题第三十二题:串联所有单词的子串
17 0