前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2023-01-08:小红定义一个仅有r、e、d三种字符的字符串中,如果仅有一个长度不小于2的回文子串,那么这个字符串定义为"好

2023-01-08:小红定义一个仅有r、e、d三种字符的字符串中,如果仅有一个长度不小于2的回文子串,那么这个字符串定义为"好

作者头像
福大大架构师每日一题
发布2023-02-01 11:57:39
7260
发布2023-02-01 11:57:39
举报

2023-01-08:小红定义一个仅有r、e、d三种字符的字符串中,

如果仅有一个长度不小于2的回文子串,那么这个字符串定义为"好串"。

给定一个正整数n,输出长度为n的好串有多少个。

结果对10 ^ 9 + 7取模, 1 <= n <= 10^9。

示例:

n = 1, 输出0,

n = 2, 输出3,

n = 3, 输出18。

来自阿里。

答案2023-01-08:

打表找规律。reer好串,因为能找到两个回文子串。所以回文子串长度要么是2,要么是3。

符合子串的要么是xx,要么是xyx。注意xxx不是好串。

时间复杂度:O(1)。

空间复杂度:O(1)。

代码用rust和solidity编写。

代码用rust编写。代码如下:

代码语言:javascript
复制
use std::iter::repeat;
fn main() {
    for i in 1..=10 {
        println!("长度为{}, 答案:{},{}", i, num1(i), num2(i));
    }
}

// 暴力方法
// 为了观察规律
// 具体方法论,在体系学习班,章节39 : 根据对数器找规律
fn num1(n: i32) -> i32 {
    let mut p: Vec<u8> = repeat(0).take(n as usize).collect();
    return process1(&mut p, 0);
}

fn process1(p: &mut Vec<u8>, i: i32) -> i32 {
    if i == p.len() as i32 {
        let mut dp = get_manacher_dp(p);
        let mut cnt = 0;
        for p in dp.iter() {
            if p - 1 > 3 {
                return 0;
            }
            if p - 1 >= 2 {
                cnt += 1;
            }
            if cnt > 1 {
                return 0;
            }
        }
        return if cnt == 1 { 1 } else { 0 };
    } else {
        let mut ans = 0;
        p[i as usize] = 'r' as u8;
        ans += process1(p, i + 1);
        p[i as usize] = 'e' as u8;
        ans += process1(p, i + 1);
        p[i as usize] = 'd' as u8;
        ans += process1(p, i + 1);
        return ans;
    }
}

fn get_manacher_dp(s: &mut Vec<u8>) -> Vec<i32> {
    let mut str = manacher_string(s);
    let mut p_arr: Vec<i32> = repeat(0).take(str.len()).collect();
    let mut cc = -1;
    let mut rr = -1;
    for i in 0..str.len() as i32 {
        p_arr[i as usize] = if rr > i {
            get_min(p_arr[(2 * cc - i) as usize], rr - i)
        } else {
            1
        };
        while i + p_arr[i as usize] < str.len() as i32 && i - p_arr[i as usize] > -1 {
            if str[(i + p_arr[i as usize]) as usize] == str[(i - p_arr[i as usize]) as usize] {
                p_arr[i as usize] += 1;
            } else {
                break;
            }
        }
        if i + p_arr[i as usize] > rr {
            rr = i + p_arr[i as usize];
            cc = i;
        }
    }
    return p_arr;
}

fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
    if a < b {
        a
    } else {
        b
    }
}

fn manacher_string(s: &mut Vec<u8>) -> Vec<u8> {
    let mut res: Vec<u8> = repeat(0).take(s.len() * 2 + 1).collect();
    let mut index = 0;
    let mut i = 0;
    while i != res.len() {
        res[i as usize] = if (i & 1) == 0 {
            '#' as u8
        } else {
            index += 1;
            s[index - 1]
        };
        i += 1;
    }
    return res;
}

// 正式方法
// 观察规律之后,把规律变成代码
fn num2(n: i32) -> i32 {
    if n == 1 {
        return 0;
    }
    if n == 2 {
        return 3;
    }
    if n == 3 {
        return 18;
    }
    return 6 * (n + 1);
}

代码用solidity编写。diam如下:

代码语言:javascript
复制
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Hello{
    function main() public pure returns (int32[] memory){
        int32[] memory ans = new int32[](10);
    for (int32 i = 1; i <= 10; i++) {
      ans[uint32(i-1)] = num2(i);
    }
    return ans;
    }

  // 正式方法
  // 观察规律之后,把规律变成代码
  function  num2(int32 n) public pure returns(int32) {
    if (n == 1) {
      return 0;
    }
    if (n == 2) {
      return 3;
    }
    if (n == 3) {
      return 18;
    }
    return 6 * (n + 1);
  }

}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-01-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档