leetcode每日题2
0x00
同意暴力解法还是两个for循环。
考虑题目所给特殊条件:1必有唯一解 2元素不重复
对于该唯一解,假设下标分别为ij,i<j。我们先假定j已知,那么从0-j-1必然存在一个值=target-num[j]。这个值的下标即为i。如果找不到,那说明j是错误的,应该换一个j。
因此我们让j从1到num.size()-1,对于每一个j我们不需要遍历0-j-1 ,可以用hashmap来记录前面已经出现过的元素,j增加时只需多记录一个元素即可。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int,int> map{};
vector<int> ret{};
for(int i=0;i<nums.size();i++){
int left=target-nums[i];
if(map.find(left)!=map.end()){
ret.push_back(map[left]);
ret.push_back(i);
return ret;
}
map[nums[i]]=i;
}
return ret;
}
};
0x01
要求在原数组上进行排序,如果是新数组那么双指针很简单,现在没有空间。实际上根据给的特殊条件,还是有的,因为我们可以在空出的位置进行排序。既然是末尾空出来了,那就从nums1 nums2中用双指针不断找最大的放在末尾就行了。(我做的时候是将前面空出来,不断找最小的,思路是一样的)。一个特殊情况就是,nums1和nums2有一方的指针会先到尽头,说明该方的元素全部有序了,只需要把剩下一方的全部复制到末尾即可
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
for(int i=m-1;i>=0;i--)nums1[i+n]=nums1[i];
int p1=n;
int p2=0;
int cnt=0;
for(;p1<(m+n)&&p2<n;){
if(nums1[p1]<nums2[p2]) nums1[cnt++]=nums1[p1++];
else nums1[cnt++]=nums2[p2++];
}
if(p2!=n){
for(;p2!=n;){
nums1[cnt++]=nums2[p2++];
}
}
}
};