1. Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
- 思路1:two pointers从两边找。比 target 大右指针向左(变小)。比 target 小左指针向右(变大)。
- 注意:
- 题目没说排序了,所以要提前排序
- 因为排序就就全乱了,所以要记录数和index的关系
- 复杂度:时间O(log n), 空间O(n)
struct Pair{
int num;
int index;
};
int compare(Pair &a, Pair &b) {
return a.num < b.num;
}
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int l = 0, r = nums.size() - 1;
vector<Pair> pairs(nums.size(), {0, 0});
for(int i = 0; i < nums.size(); i++) {
pairs[i].num = nums[i];
pairs[i].index = i;
}
sort(pairs.begin(), pairs.end(), compare);
while(l < r) {
if(pairs[l].num + pairs[r].num > target) {
r--;
} else if(pairs[l].num + pairs[r].num < target) {
l++;
} else {
break;
}
}
return {pairs[l].index, pairs[r].index};
}
};
- 思路2 :我没想出来,是从别人那里看的。因为保证都存在,所以呢,就往后扫描。把之前的数和index存在map里面。每次在 i 这个位置,就需要一个want = target - num[i] 来凑。want如果存在于map中,返回index即可。我觉得这个思路主要是利用了题目里保证一定有一对数。考虑到有可能重复。所以就每扫描一个数,往map里存一个数。
- 复杂度:时间空间都是O(n)
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> numIndex;
for(int i = 0; i < nums.size(); i++) {
int want = target - nums[i];
if(numIndex.find(want) != numIndex.end()) {
return {numIndex[want], i};
}
numIndex[nums[i]] = i;
}
return {0, 0};
}
};
4. Median of Two Sorted Arrays
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
You may assume nums1 and nums2 cannot be both empty.
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
- 思路:这题目一开始没有思路,看了看youtube Hua Hua的讲解视频才明白。
- 两个数组,长度为n1, n2
- 则中位数在 k = (n1 + n2 + 1) / 2 处(如果合成一个数组)。
- 两个数组的可能中间值C[k-1] 和 C[k] 一定从A[m1 - 1], A[m1], B[m2 -1], B[M2]中产生
- C[k-1] < C[k], 所以 A[m1-1], B[m2-1] < A[m1], B[m2]
- 所以二分搜索的条件就是
- A[m1] < B[m2 - 1] , l = m1 + 1
- else, r = m1
- 只需对小的数组进行二分搜索即可
- 注意:
- 如果二分搜索超出了数组的界限,则说明整个数组都比另一个数组大或小,这样中值不会出现在当前数组中。
- 二分搜索那里是关键。
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
int n1 = nums1.size();
int n2 = nums2.size();
if(n1 > n2) return findMedianSortedArrays(nums2, nums1);
int k = (n1 + n2 + 1) / 2;
int l = 0, r = n1;
while(l < r) {
int m1 = (l + r) / 2;
int m2 = k - m1;
if(nums1[m1] < nums2[m2 - 1]) {
l = m1 + 1;
} else {
r = m1;
}
}
int m1 = l;
int m2 = k - l;
int c1 = max( m1 <= 0 ? INT_MIN : nums1[m1 - 1],
m2 <= 0 ? INT_MIN : nums2[m2 - 1]);
if ((n1 + n2) % 2 == 1)
return c1;
int c2 = min( m1 >= n1 ? INT_MAX : nums1[m1],
m2 >= n2 ? INT_MAX : nums2[m2]);
return (c1 + c2) * 0.5;
}
};