给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1。
返回使 A 中的每个值都是唯一的最少操作次数。
示例 1:
输入:[1,2,2]
输出:1
解释:经过一次 move 操作,数组将变为 [1, 2, 3]。
示例 2:
输入:[3,2,1,2,1,7]
输出:6
解释:经过 6 次 move 操作,数组将变为 [3, 4, 1, 2, 5, 7]。
可以看出 5 次或 5 次以下的 move 操作是不能让数组的每个值唯一的。
提示:
0 <= A.length <= 40000
0 <= A[i] < 40000
我是用哈希表做的,解题的关键在于,哈希表的初始化。
有可能在经过n次的递增,key+1的值并没有记录在哈希表的键值里面,
所以需要提前录入,进行一个哈希表的初始化。
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
class Solution {
public:
int minIncrementForUnique(vector<int>& A) {
int maxVal = 0;
int num = 0;
if (A.empty()) {
return 0;
}
/* 求最大值 */
for (int i = 0; i < A.size(); i++) {
if (A[i] > maxVal) {
maxVal = A[i];
}
}
/* 空间换时间 */
maxVal = 2 * maxVal + 1;
/* 初始化哈希表:初始值为0 */
for (int i = 0; i < maxVal; i++) {
m_map[i] = 0;
}
/* 记录数组的哈希,记录重复值 */
for (int i = 0; i < A.size(); i++) {
if (m_map.count(A[i])) {
m_map[A[i]]++;
}
}
/* 如果存在key大于1,则key+1的value需要加上key值的(value-1),依次类推 */
for (int i = 0; i < maxVal; i++) {
if (m_map[i] > 1) {
num += m_map[i] - 1;
m_map[i + 1] += (m_map[i] - 1);
m_map[i] = 1;
}
}
return num;
}
private:
unordered_map<int, int> m_map;
};
// 超时的递归算法:
//class Solution {
//public:
// int minIncrementForUnique(vector<int>& A) {
// num = 0;
// for (int i = 0; i < A.size(); i++) {
// backtrace(A[i]);
// }
// return num;
// }
//
// void backtrace(int key) {
// if (m_set.count(key)) {
// num++;
// backtrace(key + 1);
// }
// else {
// m_set.insert(key);
// }
//
// }
//
//private:
// int num;
// set<int> m_set;
//
//};
int main() {
vector<int> test = { 3,2,1,2,1,7 };
Solution* ps = new Solution();
cout << ps->minIncrementForUnique(test) << endl;
return 0;
}