18. 4Sum(C++)

注:此博客不再更新,所有最新文章将发表在个人独立博客limengting.site。分享技术,记录生活,欢迎大家关注

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note: The solution set must not contain duplicate quadruplets.

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.

A solution set is:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]

求纠错:

class Solution {
public:
// 把返回类型改成vector>&
    vector> fourSum(vector& nums, int target) {
    // 改为vector>& res = *(new vector>);
        vector> res;
        int len = nums.size();
        if (len < 4) return res;
        sort(nums.begin(), nums.end());
        int max = nums[len - 1];
        if (4 * nums[0] > target || 4 * max < target) return res;
        
        int i, z;
        for(i = 0; i < len; i++) {
            z = nums[i];
            if (i > 0 && z == nums[i - 1])// avoid duplicate
				continue;
			if (z + 3 * max < target) // z is too small
				continue;
			if (4 * z > target) // z is too large
				break;
			if (4 * z == target) { // z is the boundary
				if (i + 3 < len && nums[i + 3] == z)
					res.push_back({z, z, z, z});
				break;
			}

			threeSumForFourSum(nums, target - z, i + 1, len - 1, res, z);
		}
		
		return res;
    }
    
    // 返回类型改成void,倒数第二个形参的类型改成vector>&
    vector> threeSumForFourSum(vector& nums, int target, int low, int high, vector> fourSumList,int z1) {
		// 删除这一行
		vector> res1;
		if (low + 1 >= high)
			// 改成return ;
			return res1;

		int max = nums[high];
		if (3 * nums[low] > target || 3 * max < target)
			// 改成return ;
			return res1;

		int i, z;
		for (i = low; i < high - 1; i++) {
			z = nums[i];
			if (i > low && z == nums[i - 1]) // avoid duplicate
				continue;
			if (z + 2 * max < target) // z is too small
				continue;

			if (3 * z > target) // z is too large
				break;

			if (3 * z == target) { // z is the boundary
				if (i + 1 < high && nums[i + 2] == z)
					fourSumList.push_back({z1, z, z, z});
				break;
			}

			twoSumForFourSum(nums, target - z, i + 1, high, fourSumList, z1, z);
		}
	}
	
	// 返回类型改成vector>&,倒数第三个参数的类型也改成vector>&
	vector> twoSumForFourSum(vector& nums, int target, int low, int high, vector> fourSumList, int z1, int z2) {
	// 改成vector>& res2 = *(new vector>);
	    vector> res2;
		if (low >= high)
			return res2;

		if (2 * nums[low] > target || 2 * nums[high] < target)
			return res2;

		int i = low, j = high, sum, x;
		while (i < j) {
			sum = nums[i] + nums[j];
			if (sum == target) {
				fourSumList.push_back({z1, z2, nums[i], nums[j]});

				x = nums[i];
				while (++i < j && x == nums[i]) // avoid duplicate
					;
				x = nums[j];
				while (i < --j && x == nums[j]) // avoid duplicate
					;
			}
			if (sum < target)
				i++;
			if (sum > target)
				j--;
		}
		return res2;
	}
};

正确代码:

#include
#include
#include
using namespace std;
void print(vector>&);
class Solution {
public:
	vector>& fourSum(vector& nums, int target) {
		vector>& res = *(new vector>);
		int len = nums.size();
		if (len < 4) return res;
		sort(nums.begin(), nums.end());
		int max = nums[len - 1];

		if (4 * nums[0] > target || 4 * max < target) return res;

		int i, z;
		for (i = 0; i < len; i++) {
			z = nums[i];
			if (i > 0 && z == nums[i - 1])// avoid duplicate
				continue;
			if (z + 3 * max < target) // z is too small
				continue;
			if (4 * z > target) // z is too large
				break;
			if (4 * z == target) { // z is the boundary
				if (i + 3 < len && nums[i + 3] == z)
					res.push_back({ z, z, z, z });
				break;
			}

			threeSumForFourSum(nums, target - z, i + 1, len - 1, res, z);
		}

		return res;
	}

	void threeSumForFourSum(vector& nums, int target, int low, int high, vector>& fourSumList, int z1) {

		if (low + 1 >= high)
			return ;

		int max = nums[high];
		if (3 * nums[low] > target || 3 * max < target)
			return ;

		int i, z;
		for (i = low; i < high - 1; i++) {
			z = nums[i];
			if (i > low && z == nums[i - 1]) // avoid duplicate
				continue;
			if (z + 2 * max < target) // z is too small
				continue;

			if (3 * z > target) // z is too large
				break;

			if (3 * z == target) { // z is the boundary
				if (i + 1 < high && nums[i + 2] == z)
					fourSumList.push_back({ z1, z, z, z });
				break;
			}

			twoSumForFourSum(nums, target - z, i + 1, high, fourSumList, z1, z);
		}
	}

	vector>& twoSumForFourSum(vector& nums, int target, int low, int high, vector>& fourSumList, int z1, int z2) {
		vector>& res2 = *(new vector>);
		if (low >= high)
			return res2;

		if (2 * nums[low] > target || 2 * nums[high] < target)
			return res2;

		int i = low, j = high, sum, x;
		while (i < j) {
			sum = nums[i] + nums[j];
			if (sum == target) {
				fourSumList.push_back({ z1, z2, nums[i], nums[j] });

				x = nums[i];
				while (++i < j && x == nums[i]) // avoid duplicate
					;
				x = nums[j];
				while (i < --j && x == nums[j]) // avoid duplicate
					;
			}
			if (sum < target)
				i++;
			if (sum > target)
				j--;
		}
		return res2;
	}
};

int main() {
	vector S = {
		1,0,-1,0,-2,2
	};
	int number;
	//while (cin >> number)
	//	S.push_back(number);
	int target = 0;
	//cin >> target;
	Solution sol;
	print( sol.fourSum(S, target) );
	return 0;
}

void print(vector>& v) {
	int size = v.size();
	for (int i = 0; i < size; i++) {
		vector& v1 = v[i];
		int n = v1.size();
		for (int j = 0; j < n; j++) {
			cout << v1[j] << " " ;
		}
		cout << endl;
	}
}

最后的输出函数可以改成:

void print(vector>& v) {

	for (auto v1 : v) { // 用迭代器遍历v,每次取一个值赋值给v1
		for (auto v2 : v1) {  // 用迭代器遍历v1,每次取一个值赋值给v2
			cout << v2 << " "; // 输出v2
		}
		cout << endl;
	}

你可能感兴趣的:(leetcode)