leetcode字符串剑指58_1143最长公共子序列_300最长递增子序列_38字符串排列

19 篇文章 0 订阅

剑指58
问题类型:字符串反转

class Solution {
	public:
		void reverselen(string &a, int from, int to) {
			char ch;
			while (from < to) {
				ch = a[from];
				a[from] = a[to];
				a[to] = ch;
				from++;
				to--;
			}
		}
		string reverseLeftWords(string s, int n) {
			int len = s.size();
			if (n > 0) {
				reverselen(s, 0, len - 1);
				reverselen(s, 0, len - n - 1);
				reverselen(s, len - n, len - 1);
			}
			return s;
		}
};

leetcode1143
最长公共子序列

问题类型: LCS 动态规划,通过区分最后一个字符是否相同,相同则是前一个加一,否则是两个字符串减少一个字符中较大的情况

class Solution {
	public:
		int longestCommonSubsequence(string text1, string text2) {
			int size1 = text1.size();
			int size2 = text2.size();
			int ans = 0;
			vector<vector<int>> LCS(size1 + 1, vector<int>(size2 + 1));
			for (int i = 0; i <= size1; ++i) {
				LCS[i][0] = 0;
			}
			for (int j = 0; j <= size2; ++j) {
				LCS[0][j] = 0;
			}
			for (int i = 1; i <= size1; ++i) {
				for (int j = 1; j <= size2; ++j) {
					if (text1[i - 1] == text2[j - 1]) {
						LCS[i][j] = LCS[i - 1][j - 1] + 1;
					} else {
						LCS[i][j] = max(LCS[i][j - 1], LCS[i - 1][j]);
					}
					if (LCS[i][j] > ans) {
						ans = LCS[i][j];
					}
				}
			}
			return ans;
		}
};

leetcode300
LIS 可以用LCS解决,也可以直接用动态规划解决

class Solution {
	public:
		int lengthOfLIS(vector<int> &nums) {
			vector<int> ans(nums.size() + 1);
			int len = nums.size();
			for(int i = 0; i < len; ++i)
			{
				ans[i] = 1;
			}
			for(int i = 0; i < len; ++i)
			{
				int Max = 1;
				for(int j = 0; j < i; ++j)
				{
					if(nums[i] > nums[j] &&Max < ans[j] + 1)
					{
						Max = ans[j] + 1;		
					}
				}
				ans[i] = Max;			
			}
			int sh = 0;
			for(int i = 0; i < len; ++i)
			{
				if(sh < ans[i])
					sh = ans[i];
			}
			return sh;
		}
};

leecode_OFFer_38
两种方法:
1.通过递归
2.通过进行大小变化

class Solution {
	public:
		vector<string> ans;
		vector<int> vis;

		void chain(string s, int a, int n, string &t) {
			if (n == a) {
				ans.push_back(t);
				return ;
			}
			for (int i = 0; i < n; ++i) {
				if (vis[i] || (i > 0 && vis[i - 1] == 0 && s[i] == s[i - 1]))
					continue;
				vis[i] = 1;
				t.push_back(s[i]);
				chain(s, a + 1, n, t);
				t.pop_back();
				vis[i] = 0;
			}
		}

		vector<string> permutation(string s) {
			int len = s.size();
			vis.resize(len);
            sort(s.begin(), s.end());
			for (int i = 0; i < len; ++i) {
				vis[i] = 0;
			}
			string ch;
			chain(s, 0, len, ch);
			return ans;
		}
};
class Solution {
	public:
		bool gethigher(string &s, int n) {
			int i = n - 2;
			while (i >= 0 && s[i] >= s[i + 1]) {
				i--;
			}
			if (i < 0)
				return false;
			int j = n - 1;
			while (s[j] <= s[i])
				j--;
			swap(s[i], s[j]);
			sort(s.begin() + i + 1, s.end());
			cout << s << endl;
			return true;
		}


		vector<string> permutation(string s) {
			int len = s.size();
			vector<string> ans;
			sort(s.begin(), s.end());
			ans.push_back(s);
			while (gethigher(s, len)) {
				ans.push_back(s);
			}


			return ans;
		}
};

其中第二种难点是在于排序的理解:首先从最低位(字符串最高位)+ 1开始遍历寻找更低位高于它,并找到在低于此位范围内大于它的最低位,进行交换,直至字符串最大
2.注意:交换之后可能会跳过一些位置所以交换之后将之后的字符串再升序排序,确保增幅最小

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值