leetcode刷题-Array#1

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;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值