Create Maximum Number

找了一份比较清晰的解释,DP+贪心:https://discuss.leetcode.com/topic/32252/c-dp-greedy-solution-should-be-easy-to-understand/5

最近没空仔细研究了,记录一下二刷的时候认真看看

class Solution {
public:
	vector<int> maxNumber(vector<int>& nums1, vector<int>& nums2, int k) {
		vector<int> ans;
		if (!nums1.size() && !nums2.size() || !k)
			return ans;

		ans.resize(k);
		int n = nums1.size(), m = nums2.size();
		vector<string> dp1(min(k, n)), dp2(min(k, m));
		vector<string> dpprev1(n), dpcur1(n), dpprev2(m), dpcur2(m);
		//dp求最大子串
		for (int i = 0; i < dp1.size(); ++i) {
			string tmpval(i + 1, 0);
			dp1[i] = tmpval;
			if (!i) {
				for (int j = 0; j < n; ++j) {
					dpprev1[j] = "";
					dpprev1[j] += (char)(nums1[j] + '0');
					dp1[i] = max(dp1[i], dpprev1[j]);
					if (j)
						dpprev1[j] = max(dpprev1[j], dpprev1[j - 1]);

				}
			}
			else {
				for (int j = i; j < n; ++j) {
					dpcur1[j] = tmpval;

					dpcur1[j] = max(dpcur1[j], dpprev1[j - 1] + (char)(nums1[j] + '0'));

					dp1[i] = max(dp1[i], dpcur1[j]);
					if (j >= i)
						dpcur1[j] = max(dpcur1[j], dpcur1[j - 1]);
				}
				dpprev1 = dpcur1;
			}

		}


		//dp求最大子串
		for (int i = 0; i < dp2.size(); ++i) {
			string tmpval(i + 1, 0);
			dp2[i] = tmpval;
			if (!i) {
				for (int j = 0; j < m; ++j) {
					dpprev2[j] = "";
					dpprev2[j] += (char)(nums2[j] + '0');
					dp2[i] = max(dp2[i], dpprev2[j]);
					if (j)
						dpprev2[j] = max(dpprev2[j], dpprev2[j - 1]);
				}
			}
			else {
				for (int j = i; j < m; ++j) {
					dpcur2[j] = tmpval;

					dpcur2[j] = max(dpcur2[j], dpprev2[j - 1] + (char)(nums2[j] + '0'));

					dp2[i] = max(dp2[i], dpcur2[j]);
					if (j >= i)
						dpcur2[j] = max(dpcur2[j], dpcur2[j - 1]);
				}
				dpprev2 = dpcur2;
			}

		}


		string tmpans(k, 0), v = "";

		if (!dp1.size()) {
			getAns(v, dp2[k - 1], ans, tmpans);
		}
		else {
			for (int i = 0; i <= min(k, (int)dp1.size()); ++i) {
				if (i == 0) {
					if (dp2.size() >= k)
						getAns(v, dp2[k - 1], ans, tmpans);
				}
				else if (i < k) {
					if (dp2.size() >= k - i)
						getAns(dp1[i - 1], dp2[k - i - 1], ans, tmpans);
				}
				else {
					if (dp1.size() >= k)
						getAns(dp1[k - 1], v, ans, tmpans);
				}
			}

		}

		return ans;
	}

private:
	void getAns(string &s1, string &s2, vector<int> &ans, string &tmpans) {
		string res;
		if (!s1.size())
			res = s2;
		else if (!s2.size())
			res = s1;
		else {
			int id1 = 0, id2 = 0;

			while (id1 < s1.size() && id2 < s2.size()) {
				if (s1[id1] > s2[id2]) {
					res += s1[id1++];
				}
				else if (s1[id1] < s2[id2]) {
					res += s2[id2++];
				}
				else {
					if (s1.substr(id1) >= s2.substr(id2))
						res += s1[id1++];
					else
						res += s2[id2++];
				}
			}
			while (id1 < s1.size())
				res += s1[id1++];
			while (id2 < s2.size())
				res += s2[id2++];
		}
		//copy
		if (res > tmpans) {
			tmpans = res;
			for (int i = 0; i < res.size(); ++i)
				ans[i] = (res[i] - '0');
		}
	}
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值