一、数组篇–简单难度(出现频率降序)

#1 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
1、暴力解法(时间复杂度O(n²),空间复杂度O(1):
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans;
int n = nums.size();
for( int i=0; i < n;i++){
int reslut = target - nums[i];
for( int j=i+1; j < n; j++){ //注意这里向下查找时需要从i的下一个开始查找!
if(nums[j]==reslut){
ans.push_back(i);
ans.push_back(j);
return ans;
}
}
}
return ans;
}
};
2、排序+双指针法
先使用sort排好序O(nlogn),排序好后从数组两头向中间遍历O(n)得到结果。
时间复杂度nlogn),空间复杂度O(n)。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans ;
vector<int> temp;
temp = nums;
sort(temp.begin(),temp.end());
int n = temp.size();
int i = 0;
int j = n-1;
while(i<j){
if(temp[i]+temp[j] < target)
i++;
else if(temp[i]+temp[j] > target)
j--;
else
break;
}
if(i<j){ //此处去原数组寻找目标值的时候,两个值一定要分开查找且唯一。否则可能会出现多个目标值或重复的目标值
for( int k=0; k<n;k++){
if(i< n && nums[k]==temp[i]){
ans.push_back(k);
i = n;
}
else if(j< n && nums[k]==temp[j]){
ans.push_back(k);
j = n;
}
if(i==n && j==n) return ans;
}
}
return ans;
}
};
3.hash法
利用undered_map数组构造映射,Key是数组nums里数字,value是该数字的index。遍历nums[i],查找hash表中是否存在target-nums[i],如若存在则将i与hash_map[target-nums[i]]放入输出结果的数组中,若不存在把该数字的index放到hash表中
hash_map[nums[i]] = i;
时间复杂度O(n),空间复杂度O(n)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> ans;
unordered_map<int , int> hash_map; //Key是数组nums里数字,value是该数字的index
int n= nums.size();
for( int i=0; i<n; i++){
int result = target - nums[i];
if(hash_map.find(result) != hash_map.end()){
ans.push_back(hash_map[result]);
ans.push_back(i);
return ans;
}
else
hash_map[nums[i]] = i; //未找到时,将其放入道hash表中
}
return ans;
}
};
本文详细解析了LeetCode经典题目“两数之和”的三种解法:暴力解法、排序+双指针法及hash法。通过具体示例,深入探讨了每种方法的时间复杂度和空间复杂度,帮助读者理解并掌握高效算法。

被折叠的 条评论
为什么被折叠?



