Submission Details [leetcode] 算法的改进

最先看到这一题,直觉的解法就是len从1到s1.size()-1,递归调用比较s1和s2长度为len的子串是否相等,以及剩余部分是否相等。

将s1分成s1[len + rest],分别比较s2[len + rest]和s2[rest + len]

代码如下:

    bool isScramble(string s1, string s2) {
		return find(s1, s2);
    }

	bool find(string s1, string s2) {
		if (s1.compare(s2) == 0) return true;
		for (int i = 1; i < s1.size(); i++)
		{
			if (find(s1.substr(0, i), s2.substr(0,i)) && find(s1.substr(i), s2.substr(i)))
				return true;
			if (find(s1.substr(0, i), s2.substr(s2.size() - i)) && find(s1.substr(i), s2.substr(0, s2.size() - i)))
				return true;
		}
		return false;
    }

是一个TLE的算法

改进点1:在find中查看s1和s2是否字母相同,如果不同,返回false

代码如下:

    bool isScramble(string s1, string s2) {
		return find(s1, s2);
    }

	bool find(string s1, string s2) {
		if (!haveSameChar(s1, s2)) return false;
		if (s1.compare(s2) == 0) return true;
		for (int i = 1; i < s1.size(); i++)
		{
			if (find(s1.substr(0, i), s2.substr(0,i)) && find(s1.substr(i), s2.substr(i)))
				return true;
			if (find(s1.substr(0, i), s2.substr(s2.size() - i)) && find(s1.substr(i), s2.substr(0, s2.size() - i)))
				return true;
		}
		return false;
    }

	bool haveSameChar(string& s1, string& s2)
	{
		int chars[26] = {0};
		for (int i = 0; i < s1.size(); i++)
		{
			chars[s1[i] - 'a'] ++;
		}
		for (int i = 0; i < s2.size(); i++)
		{
			if (chars[s2[i] - 'a'] == 0)  return false;
			chars[s2[i] - 'a'] --;
		}
		return true;
	}

改进点2:存储状态,将问题转换为三维DP

dp(i, j, l):s1[i...i+l]和s2[j...j+l]是否满足要求

dp(i, j, l) = dp(i, j, k) && dp(i + k, j + k, l - k) || dp(i, j + l - k, k) && dp(i + k, j, l - k)

    vector<vector<vector<int>>> dp;
    bool isScramble(string s1, string s2) {
        int size = s1.size();
        dp = vector<vector<vector<int>> > (size, vector<vector<int>>(size, vector<int>(size + 1)));
        return find(s1, s2, 0, 0, size);
    }

    bool find(string & s1, string & s2, int l1, int l2, int length)
    {
        if (dp[l1][l2][length] != 0)
            return dp[l1][l2][length] == 1;
        dp[l1][l2][length] = -1;
        if (length == 1)
            dp[l1][l2][length] = ((s1[l1] == s2[l2]) ? 1 : -1);
        for (int len = 1; len < length; len++)
        {
            if (find(s1, s2, l1, l2, len) && find(s1, s2, l1 + len, l2 + len, length - len))
            {
                dp[l1][l2][length] = 1;
                break;
            }
            if (find(s1, s2, l1, l2 + length - len, len) && find(s1, s2, l1 + len, l2, length - len))
            {
                dp[l1][l2][length] = 1;
                break;
            }
        }
        return dp[l1][l2][length] == 1;
    }
时间: 2024-10-10 15:42:35

Submission Details [leetcode] 算法的改进的相关文章

Submission Details [leetcode] ---- inplace 线性时间 的两种思路

两种思路都利用了输入的数组A,若A中存在i,则给A[i]作为标记. 因为A中的n个元素存在>n和<=0的,所以第一个缺失的正整数一定在[1-n+1]之间. 第一种思路是将标记设为一个特定的数.因为改变数值会影响该位置原来存的值,所以需要在一个循环里依次处理所有"原来的值". 例如数组为{2,3,4,1}.对第一个数2,我们将位置(2-1)=1标记为-MAX_INT,数组变为{2,-MAX_INT,4,1},丢失了3,所以应记录下数组原来的值,并继续将位置(3-1)=2标记为

LeetCode算法编程(两题)

今天看到酷壳推荐的国外编程LeetCode算法编程网站,上面目前有154道算法题,感觉很有意思,平常工作也比较忙,现在很少有时间来锻炼算法相关的东西,有空的时候静下心来,温习下基础,活跃下自已的思路,也是有必要的.先做了几道,后面会陆续补充其它的题目. 1.题目-PlusOne Given a non-negative number represented as an array of digits, plus one to the number. The digits are stored s

Leetcode 算法题--ReverseWordsInString

翻转字符串,想到什么写什么...我的做法是先trim掉空格,然后从字符串尾部开始扫描,遇到空格则认为一个单词结束,然后copy这个单词.需要注意的地方在于当扫描到最后一个单词的第一个字母时(譬如the sky is blue的t字母),注意单词长度的自增逻辑. 网上还有人的做法是反转整个字符串,然后逐个翻转单词. 1 package edu.hust.sse.Problems; 2 3 //Given s = "the sky is blue", 4 //return "bl

leetcode 算法 之 马拉松算法(Manacher&#39;s algorithm)(未完成)

马拉松算法:马拉松算法是用来计算一个字符串中最长的回文字符串(对称字符串,如aba abba). 首先,我们拿到一个字符串S,然后在S中的每个字符之间加#.例如:S="abcb" T="a#b#c#b" 我们T字符串的每一个T[i]向延伸d个字符 使得 T[i-d,i+d]是一个回文字符串.你会立刻发现,d就是以T[i]为中心的最长回文字符串的长度. 我们建立一个P数组,是的P数组的长度等于T的长度,每一个P[i]的值表示对应的T[i]为中心的最大回文字符串的长度.

数据结构实践——归并排序算法的改进

本文是针对[数据结构基础系列(9):排序]的项目. [项目 - 归并排序算法的改进] 采用归并排序.快速排序等高效算法进行排序,当数据元素较少时(如n≤64),经常直接使用直接插入排序算法等高复杂度的算法.这样做,会带来一定的好处,例如归并排序减少分配.回收临时存储区域的频次,快速排序减少递归层次等. 试按上面的思路,重新实现归并排序算法. [参考解答] #include <stdio.h> #include <malloc.h> #include <stdlib.h>

leetcode算法: Find Bottom Left Tree Value

leetcode算法: Find Bottom Left Tree Value Given a binary tree, find the leftmost value in the last row of the tree. Example 1:Input: 2 / \ 1 3 Output:1Example 2: Input: 1 / \ 2 3 / / \ 4 5 6 / 7 Output:7Note: You may assume the tree (i.e., the given ro

LeetCode算法练习PlusOne

今天看到酷壳推荐的国外编程LeetCode算法编程网站,上面目前有154道算法题,感觉很有意思,平常工作也比较忙,现在很少有时间来锻炼算法相关的东西,有空的时候静下心来,温习下基础,活跃下自已的思路,也是有必要的.下午先做了个简单的题,后面会陆续补充其它的题目. 1.题目 Given a non-negative number represented as an array of digits, plus one to the number. The digits are stored such

ISAP算法对 Dinic算法的改进

ISAP算法对 Dinic算法的改进: 在刘汝佳图论的开头引言里面,就指出了,算法的本身细节优化,是比较复杂的,这些高质量的图论算法是无数优秀算法设计师的智慧结晶. 如果一时半会理解不清楚,也是正常的.但是对于一个优秀的acmer来说,其算法的本身,可以锻炼你的思维.增长见识! 下面是我对 Dinic和ISAP的认识: Dinic算法比较值钱的 EK算法来说,已经有很大的提高了,其优势在哪里呢? 就是在于他的分层思想.在层次图上增广.但是,他也有弊端. 就是每次进行增广后,对于层次图都进行了从头

KMP算法及其改进

KMP算法及其改进 字符串匹配算法也就是从一个很长的字符串里面找出与我们手中的字符串相匹配的字符串(是这个大字符串的第几个字符开始),对于这个问题我们有很简单的解法,叫BF算法,Brute Force也就是蛮力的意思,充分依靠计算能力来解决问题的方法,对于这种解法可以用下面的图片来表述: 上面的算法就是BF算法,不好之处是效率太低了,因为就像第三趟比较中那样,我们只有最后一个元素没有匹配上就要从头再来,主串的对应元素竟然要回头从第四个元素开始比较,我们明明比较到了主串的第七个元素,前面的工作全部