題目難度不定,點到什麼題就寫什麼題
ps:LeetCode真友好,題意直截了當,爽到。
1187. 使數組嚴格遞增(2020.3.25)
題意:
給你兩個整數數組 arr1 和 arr2,返回使 arr1 嚴格遞增所需要的最小「操作」數(可能爲 0)。
每一步「操作」中,你可以分別從 arr1 和 arr2 中各選出一個索引,分別爲 i 和 j,0 <= i < arr1.length 和 0 <= j < arr2.length,然後進行賦值運算 arr1[i] = arr2[j]。
如果無法讓 arr1 嚴格遞增,請返回 -1。
數據範圍:
1 <= arr1.length, arr2.length <= 2000
0 <= arr1[i], arr2[i] <= 10^9
ac:
思路:
因爲只需要比大小,所以離散化。
觀察到數據範圍只有2000,令d(i,j)表示前i個數保持嚴格遞增,且結尾爲j的最少操作次數,兩層循環dp一下就行了。
代碼順便優化了一下空間。
code:
class Solution {
public:
int makeArrayIncreasing(vector<int>& arr1, vector<int>& arr2) {
int n=arr1.size(),m=arr2.size();
//離散化
sort(arr2.begin(),arr2.end());
m=unique(arr2.begin(),arr2.end())-arr2.begin();
vector<int>temp;
for(int i=0;i<n;i++)temp.push_back(arr1[i]);
for(int i=0;i<m;i++)temp.push_back(arr2[i]);
sort(temp.begin(),temp.end());
int num=unique(temp.begin(),temp.end())-temp.begin();
for(int i=0;i<n;i++)arr1[i]=lower_bound(temp.begin(),temp.begin()+num,arr1[i])-temp.begin();
for(int i=0;i<m;i++)arr2[i]=lower_bound(temp.begin(),temp.begin()+num,arr2[i])-temp.begin();
//dp
int d[2][num],pos=0;
for(int i=0;i<2;i++)for(int j=0;j<num;j++)d[i][j]=1e9;
for(int i=0;i<m;i++)d[pos][arr2[0]]=1;
d[pos][arr1[0]]=0;
for(int i=1;i<n;i++){
pos^=1;
for(int j=0;j<num;j++)d[pos][j]=1e9;
for(int j=0;j<arr1[i];j++){//不換
d[pos][arr1[i]]=min(d[pos][arr1[i]],d[pos^1][j]);
}
int mi=1e9;
int k=0;
for(int j=0;j<m;j++){//換
while(k<num&&k<arr2[j]){
mi=min(mi,d[pos^1][k]);
k++;
}
d[pos][arr2[j]]=min(d[pos][arr2[j]],mi+1);
}
}
//ans
int ans=1e9;
for(int i=0;i<num;i++){
ans=min(ans,d[pos][i]);
}
if(ans==1e9)ans=-1;
return ans;
}
};