首页 > 其他分享 >lc336 回文对

lc336 回文对

时间:2024-03-24 13:55:45浏览次数:20  
标签:hx hy int hval lc336 words size 回文

给定字符串数组words[n],寻找二元组(i,j)满足0<=i,j<n,并且i!=j,而且words[i]+words[j]是回文串,求满足条件的二元组的个数。
1<=n<=5000; 0<=words[i].length<=300; words[i]由小写英文字母组成。

判断回文可以检查正序和逆序的哈希值是否相等来判断;在知道两字符串的长度和哈希的前提下,可以O(1)算出将它们连起来的字符串的哈希值。

using ll = long long;
using hval = pair<ll,ll>;
const ll b1 = 433, m1 = 1000000433;
const ll b2 = 439, m2 = 1000000439;
ll p1[305], p2[305];

int initialize = [](){
	p1[0] = p2[0] = 1;
	for (int i = 1; i <= 300; i++) {
		p1[i] = p1[i-1] * b1 % m1;
        p2[i] = p2[i-1] * b2 % m2;
	}
    return 0;
}();

hval get1(string &s) {
    ll hx = 0, hy = 0;
	int ns = s.size();
	for (int i = 0; i < ns; i++) {
		hx = hx * b1 + s[i]-'a'; hx %= m1;
        hy = hy * b2 + s[i]-'a'; hy %= m2;
	}
    return {hx,hy};
}

hval get2(string &s) {
    ll hx = 0, hy = 0;
	int ns = s.size();
	for (int i = ns-1; i >= 0; i--) {
		hx = hx * b1 + s[i]-'a'; hx %= m1;
        hy = hy * b2 + s[i]-'a'; hy %= m2;
	}
    return {hx,hy};
}

hval concat(int na, hval &a, int nb, hval &b) {
    ll hx = 0, hy = 0;
    auto &[ax,ay] = a;
    auto &[bx,by] = b;
	hx = ax * p1[nb] + bx; hx %= m1;
    hy = ay * p2[nb] + by; hy %= m2;
    return {hx,hy};
}

class Solution {
public:
    vector<vector<int>> palindromePairs(vector<string>& words) {
		int n = words.size();
		vector<hval> pre(n), suf(n);
		for (int i = 0; i < n; i++) {
			pre[i] = get1(words[i]);
			suf[i] = get2(words[i]);
		}
		
		vector<vector<int>> ans;
        hval u, v;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) if (i!=j) {
                u = concat(words[i].size(),pre[i],words[j].size(),pre[j]);
                v = concat(words[j].size(),suf[j],words[i].size(),suf[i]);
                if (u == v) {
                    ans.push_back({i,j});
                }
			}
		}
		return ans;
    }
};

标签:hx,hy,int,hval,lc336,words,size,回文
From: https://www.cnblogs.com/chenfy27/p/18092346

相关文章

  • 寻找符合回文数要求的数
    一、题目要求在11-999之间寻找一个数m,其中m的平方、m的立方均是回文数,依次输出他们 输出格式m次数对应的m 每输一个换一次行Inputexample:无Outputexample:m2->11m3->11m2->22m2->26m2->101m3->101m2->111m3->111m2->121m2......
  • lc1312 让字符串成为回文串的最少插入次数
    给定长为n的字符串s,每次操作可以在字符串的任意位置插入任意1个字符,如果要让s成为回文串,至少要操作多少次?1<=n<=500区间dp,记dp[i][j]表示让[i,j]区间成为回文串的最少操作次数,考虑s[i]与s[j]的相等关系进行转移。classSolution{public:intdp[505][505];intminIn......
  • lc1771 由子序列构造的最长回文串的长度
    给出两个字符串word1和word2,需要从word1和word2分别选出某个非空子序列s1和s2,要求连接s1与s2后得到回文串,求该回文串的最大长度。word1和word2长度在[1,1000]内。区间dp,将word1与word2拼接起来,转换成求单个字符串的的最长回文子序列问题,为了保证s1和s2非空,枚举word1和word2中每......
  • lc516 最长回文子序列
    给定长度为n的字符串s,求最长回文子序列的长度。1<=n<=1000区间dp,记dp[i][j]表示区间[i,j]能构成的最长回文串的长度,根据s[i]跟s[j]是否相等进行转移。classSolution{public:intdp[1005][1005];intlongestPalindromeSubseq(strings){intn=s.size()......
  • 125. 验证回文串c
    booljudge(charc){if(c>='a'&&c<='z'||c>='A'&&c<='Z'||c>='0'&&c<='9')returntrue;returnfalse;}boolisPalindrome(char*s){i......
  • 131. 分割回文串c
    /***Returnanarrayofarraysofsize*returnSize.*Thesizesofthearraysarereturnedas*returnColumnSizesarray.*Note:Bothreturnedarrayand*columnSizesarraymustbemalloced,assumecallercallsfree().*/charc[30][30];booljudge(ch......
  • leedcode- 回文链表
    毫无创意的一版:#定义一个类SolutionclassSolution:#定义一个方法isPalindrome,用于检查链表是否为回文defisPalindrome(self,head:Optional[ListNode])->bool:#如果链表为空,则它是一个回文ifnothead:returnTrue......
  • 1312. 让字符串成为回文串的最少插入次数c
    intmin;voiddfs(char*s,inthead,inttail,intcount){if(head>=tail){if(count<min)min=count;return;}if(s[head]==s[tail]){dfs(s,head+1,tail-1,count);}else{dfs(s,head+1,tail,count+1);......
  • 代码随想录算法训练营day27 | leetcode 39. 组合总和、40. 组合总和 II、131. 分割回
    目录题目链接:39.组合总和-中等题目链接:40.组合总和II-中等题目链接:131.分割回文串-中等题目链接:39.组合总和-中等题目描述:给你一个无重复元素的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target的所有不同组合,并以列表形......
  • 代码随想录算法训练营第27天|39. 组合总和|40.组合总和II|131.分割回文串
    代码随想录算法训练营第27天|39.组合总和|40.组合总和II|131.分割回文串详细布置39.组合总和本题是集合里元素可以用无数次,那么和组合问题的差别其实仅在于startIndex上的控制题目链接/文章讲解:https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%9......