算法(39)-数组求和-暴力和大根堆解法

  给两有序数组ARR1 ARR2,返回两个相加和最大的前K个。
  比如:arr1={1,2,3,4,5} arr2={3,5,7,9,11} K=4 ,则返回res={16,15,14,14}
  思路:1.所有两两相加后排序,原始,暴力的方法。
             2.大根堆  size为k 用于存放 两数和。root:右下角值;"左","上"比大小决定下一路径。 
             3.去重 两种方法:3.1  bool set[][] = new bool[arr1.length][arr2.length];
                                                          set[i][j] == false;//没进过
                                                           set[i][j] == true;//进过
                                           3.2生成一个点值的str
                                                  to_string(i1) + "_" + to_string(i2) :"1_3",表示数组中的1和3

                                                 放入unordered_set类型中。流程上先判断是否有这个字符串。

 这是非常典型的用堆解决最大最小值问题的模型。

上代码:
1.暴力解法:
 

//  这肯定对的方法
     vci topKSumTest(vci arr1, vci arr2, int topK) 
	 {
		vci all; 
		int index = 0;
		all.resize(arr1.size()* arr2.size());
		for (int i = 0; i != arr1.size(); i++) 
		{
			for (int j = 0; j != arr2.size(); j++) 
			{
				all[index++] = arr1[i] + arr2[j];
			}
		}
		sort(all.begin(),all.end());
		int m_size = all.size();
		int m_minsize = min(topK, m_size);
		vci res;//
		res.resize(m_minsize);
		index = all.size() - 1;
		for (int i = 0; i != res.size(); i++) 
		{
			res[i] = all[index--];
		}
		return res;
	}


2.大根堆解法:

// 放入大根堆中的结构
class Node_topKSum
{
public:
		int index1;// arr1中的位置
	    int index2;// arr2中的位置
	    int value;// arr1[index1] + arr2[index2]的值

	Node_topKSum(int i1, int i2, int sum)
	{
		index1 = i1;
		index2 = i2;
		value = sum;
	}
	bool operator < (const Node_topKSum& n) const
	{
	
		return  value > n.value;
	}
};
vci topKSum(vci arr1, vci arr2, int topK) 
   {
	    vci res;//由大到小 topK个
		if (arr1.size() == 0 || arr2.size() == 0 || topK < 1) 
		{
			res.push_back(0);
			return res;
		}
		int temp = arr1.size() * arr2.size();
		topK = min(topK, temp);// 不能要求超过arr
		res.resize(topK+1);
		int resIndex = 0;
		priority_queue<Node_topKSum*> maxHeap;        //生成一个大根堆 谁大谁放上面
		unordered_set <string> positionSet;                 //去重的
	
		int i1 = arr1.size() - 1;
		int i2 = arr2.size() - 1;
		//maxHeap.add(new Node(i1, i2, arr1[i1] + arr2[i2]));
		//positionSet.add(String.valueOf(i1 + "_" + i2));
		maxHeap.push(new Node_topKSum(i1, i2, arr1[i1] + arr2[i2]));//最后位置加入大根堆
		positionSet.insert(to_string(i1) + "_" + to_string(i2));
		while (resIndex != topK) 
		{
			Node_topKSum* curNode = maxHeap.top();
			maxHeap.pop();
			res[resIndex++] = curNode->value;
			i1 = curNode->index1;
			i2 = curNode->index2;
			string strleft,strtop;
			strleft = to_string(i1 - 1) + "_" + to_string(i2);  // 左位置
			strtop = to_string(i1) + "_" + to_string(i2 - 1);  //上位置
			if (!positionSet.count(strleft))
			{
				positionSet.insert(strleft);
				maxHeap.push(new Node_topKSum(i1 - 1, i2, arr1[i1 - 1] + arr2[i2]));
			}
			if (!positionSet.count(strtop))
             {
				positionSet.insert(strtop);
				maxHeap.push(new Node_topKSum(i1, i2 - 1, arr1[i1] + arr2[i2 - 1]));
			}
		}
		return res;
	}

 

posted @ 2020-02-13 08:49  jasmineTang  阅读(141)  评论(0)    收藏  举报