算法(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;
}

浙公网安备 33010602011771号