LeetCode每日一题(Split Two Strings to Make Palindrome)

You are given two strings a and b of the same length. Choose an index and split both strings at the same index, splitting a into two strings: aprefix and asuffix where a = aprefix + asuffix, and splitting b into two strings: bprefix and bsuffix where b = bprefix + bsuffix. Check if aprefix + bsuffix or bprefix + asuffix forms a palindrome.

When you split a string s into sprefix and ssuffix, either ssuffix or sprefix is allowed to be empty. For example, if s = “abc”, then “” + “abc”, “a” + “bc”, “ab” + “c” , and “abc” + “” are valid splits.

Return true if it is possible to form a palindrome string, otherwise return false.

Notice that x + y denotes the concatenation of strings x and y.

Example 1:

Input: a = “x”, b = “y”
Output: true
Explaination: If either a or b are palindromes the answer is true since you can split in the following way:
aprefix = “”, asuffix = “x”
bprefix = “”, bsuffix = “y”
Then, aprefix + bsuffix = “” + “y” = “y”, which is a palindrome.

Example 2:

Input: a = “abdef”, b = “fecab”
Output: true

Example 3:

Input: a = “ulacfd”, b = “jizalu”
Output: true
Explaination: Split them at index 3:
aprefix = “ula”, asuffix = “cfd”
bprefix = “jiz”, bsuffix = “alu”
Then, aprefix + bsuffix = “ula” + “alu” = “ulaalu”, which is a palindrome.

Example 4:

Input: a = “xbdef”, b = “xecab”
Output: false

Constraints:

1 <= a.length, b.length <= 105
a.length == b.length
a and b consist of lowercase English letters


最近抽到的都是这种思考10分钟编码两小时的题。一方面很讨厌做这种题,做出来也没什么成就感,一旦写完都不想回头多看哪怕一眼。但另一方面也深知之所以会这么讨厌这种题是因为很多基础的东西不扎实。所以哪怕烦得想砸电脑,一般也会坚持把题做完。

说回到这题, 假设:

a = “aaabbccc”
b = “cccbbaaa”

我们随便截取一下

a_prefix = “aa” a_suffix = “abbccc”
b_prefix = “cc” b_suffix = “cbbaaa”

我们再进一步把suffix切一下

a_prefix = “aa” a_middle = “abbc” a_suffix = “cc”
b_prefix = “cc” b_middle = “cbba” b_suffix = “aa”

看出点什么来了吗?
简单点说就是题目里要求的那种回文可以拆解为下面几种情况:

  1. a_middle本身是回文,且a_prefix == reverse(b_suffix),这样a_prefix + a_middle + b_suffix就是回文
  2. a_middle本身是回文,且b_prefix == reverse(a_suffix),这样b_prefix + a_middle + a_suffix就是回文
  3. b_middle本身是回文,且a_prefix == reverse(b_suffix),这样a_prefix + b_middle + b_suffix就是回文
  4. b_middle本身是回文,且b_prefix == reverse(a_suffix),这样b_prefix + b_middle + a_suffix就是回文

之所以要这样拆解是因为a_prefix == reverse(b_suffix)这类判断和a_middle为回文的判断的时间复杂度是O(Logn),并且后一步判断依依赖前一步的判断,只要其中一步不成立,那可以直接判断后面所剩的都不成立。


代码写的有点糙,脑子不够用,只能按照繁琐的来,简化一步脑子就转不过来了,大家凑活着看

impl Solution {
    pub fn check_palindrome_formation(a: String, b: String) -> bool {
        let a_chars: Vec<char> = a.chars().collect();
        let b_chars: Vec<char> = b.chars().collect();
        if a.len() % 2 == 0 {
            let mut a_border = vec![false; a.len() / 2];
            for i in 0..a.len() / 2 {
                if a_chars[i] == b_chars[a.len() - i - 1] {
                    a_border[i] = true;
                } else {
                    break;
                }
            }
            if *a_border.last().unwrap() {
                return true;
            }
            let mut b_border = vec![false; a.len() / 2];
            for i in 0..a.len() / 2 {
                if b_chars[i] == a_chars[a.len() - i - 1] {
                    b_border[i] = true;
                } else {
                    break;
                }
            }
            if *b_border.last().unwrap() {
                return true;
            }
            let mut left = a.len() / 2 - 1;
            let mut right = a.len() / 2;
            loop {
                if a_chars[left] == a_chars[right] {
                    if left == 0 {
                        return true;
                    }
                    if a_border[left - 1] || b_border[left - 1] {
                        return true;
                    }
                    left -= 1;
                    right += 1;
                } else {
                    break;
                }
            }
            let mut left = a.len() / 2 - 1;
            let mut right = a.len() / 2;
            loop {
                if b_chars[left] == b_chars[right] {
                    if left == 0 {
                        return true;
                    }
                    if a_border[left - 1] || b_border[left - 1] {
                        return true;
                    }
                    left -= 1;
                    right += 1;
                } else {
                    break;
                }
            }
        } else {
            let mut a_border = vec![false; a.len() / 2 + 1];
            for i in 0..=a.len() / 2 {
                if a_chars[i] == b_chars[a.len() - i - 1] {
                    a_border[i] = true;
                } else {
                    break;
                }
            }
            if *a_border.last().unwrap() {
                return true;
            }
            let mut b_border = vec![false; a.len() / 2 + 1];
            for i in 0..=a.len() / 2 {
                if b_chars[i] == a_chars[a.len() - i - 1] {
                    b_border[i] = true;
                } else {
                    break;
                }
            }
            if *b_border.last().unwrap() {
                return true;
            }
            let mut left = a.len() / 2;
            let mut right = a.len() / 2;
            loop {
                if a_chars[left] == a_chars[right] {
                    if left == 0 {
                        return true;
                    }
                    if a_border[left - 1] || b_border[left - 1] {
                        return true;
                    }
                    left -= 1;
                    right += 1;
                } else {
                    break;
                }
            }
            let mut left = a.len() / 2;
            let mut right = a.len() / 2;
            loop {
                if b_chars[left] == b_chars[right] {
                    if left == 0 {
                        return true;
                    }
                    if a_border[left - 1] || b_border[left - 1] {
                        return true;
                    }
                    left -= 1;
                    right += 1;
                } else {
                    break;
                }
            }
        }
        false
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值