Array & Numbers 3 - Sorted Array

1. Merge Sorted Array

Given two sorted integer arrays A and B, merge B into A as one sorted array.
void mergeSortedArray(int A[], int m, int B[], int n) {
  // 倒着来,防止覆盖!
  int index = m + n - 1, i = m - 1, j = n - 1;
  while (i >= 0 && j >= 0) {
    A[index--] = A[i] > B[j] ? A[i--] : B[j--];
  }
  /* ! 不需要再弄A里的了,B完了,那么A就是原来的A 
  while (i >= 0) {
    A[index--] = A[i--];
  } */
  while (j >= 0) {
    A[index--] = B[j--];
  }
}

2. Merge k Sorted Arrays

Do it in O(N log k).
N is the total number of integers.
k is the number of arrays.

priority_queue的使用

struct Node {
  int val;
  int x, y;  // 坐标
  Node(int a, int b, int c) : val(a), x(b), y(c) {}
  bool operator < (const Node & other) const {  // !!注意2个const
    return val > other.val; 
  } 
};

vector<int> mergekSortedArrays(vector<vector<int>>& arrays) {
  vector<int> res;
  if (arrays.empty()) return res;
  priority_queue<Node> q;
  // 如果不做<运算符的重载,需要这样写:
  // auto cmp = [](const Node &a, const Node &b) -> bool { return a.val > b.val; };
  // priority_queue<Node, vector<Node>, decltype(cmp)> q(cmp);
  for (int i = 0; i < arrays.size(); i++) {
    if (!arrays[i].empty()) {
      q.push(Node(arrays[i][0], i, 0));
    }
  }
  while (!q.empty()) {
    Node tmp = q.top();
    q.pop();
    res.push_back(tmp.val);
    if (tmp.y + 1 < arrays[tmp.x].size()) {  // !! +1, 判断放不放下一个
      q.push(Node(arrays[tmp.x][tmp.y + 1], tmp.x, tmp.y + 1));
    }
  }
  return res;
}

3. Intersection of Two Arrays

Given two arrays, write a function to compute their intersection.

方法1,sort & merge: O(nlogn),O(1)空间

vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
  vector<int> res;
  sort(nums1.begin(), nums1.end());
  sort(nums2.begin(), nums2.end());
  int i = 0, j = 0;
  while (i < nums1.size() && j < nums2.size()) {
    if (nums1[i] == nums2[j]) {
      if (res.empty() || nums1[i] != res.back())
        res.push_back(nums1[i]);
      i++;
      j++;
    } else if (nums1[i] < nums2[j]) {
      i++;
    } else {
      j++;
    }
  }
  return res;
}

方法2,sort & binary search: nums1排序,nums2依次二分查找, O(nlogn) 方法3,hash表: O(n),O(n)空间

vector<int> intersection(vector<int> &nums1, vector<int> &nums2) {
    unordered_set<int> s(nums1.begin(), nums1.end());
    vector<int> res;
    unordered_set<int> intersect;
    for(auto num : nums2) {
        if(s.find(num) != s.end())
            intersect.emplace(num);  // insert
    }
    for(auto num: intersect) res.push_back(num);
    return res;
}

4. Kth Largest Element

Find K-th largest element in an array.
In array [9,3,2,4,8], the 3rd largest element is 4.
O(n) time, O(1) extra memory.

不能用优先队列O(Nlogk),借鉴快排的partition方法

int kthLargestElement(int k, vector<int> nums) {
  if (nums.size() == 0) return -1;
  return quickSelect(nums, nums.size() - k + 1, 0, nums.size() - 1);
}
// 转换下说法nums.size() - k,第k小
int quickSelect(vector<int> &nums, int k, int start, int end) {
  if (start == end) {
    return nums[start];
  }
  int mid = start + (end - start) / 2;
  int pivot = nums[mid];
  // partition
  int i = start, j = end;
  while (i <= j) {
    while (i <= j && nums[i] < pivot) {
      i++;
    }
    while (i <= j && nums[j] > pivot) {
      j--;
    }
    if (i <= j) {
      swap(nums[i], nums[j]);
      i++;
      j--;
    }
  }  // i,j 错位了
  // 比较k和i,看在左右哪一堆
  if (start + k - 1 <= j) {
    return quickSelect(nums, k, start, j);
  }
  if (start + k - 1 >= i) {
    return quickSelect(nums, k - (i - start), i, end);
  }
  return nums[start + k - 1];
}

5. Median of two Sorted Arrays - Important!

Given A=[1,2,3,4,5,6] and B=[2,3,4,5], the median is 3.5.
Given A=[1,2,3] and B=[4,5], the median is 3.
The overall run time complexity should be O(log (m+n)).

solution

// 注意下标:K的含义,第k个,从1开始
double findMedianSortedArrays(vector<int> A, vector<int> B) {
  int len = A.size() + B.size();
  if (len % 2 == 1) {
    return findKthNum(A, 0, B, 0, len / 2 + 1);  // 注意:kth从1开始, 0不好想
  } else {
    return (findKthNum(A, 0, B, 0, len / 2) +
            findKthNum(A, 0, B, 0, len / 2 + 1)) / 2.0;  // 注意double, 2.0!
  }
}
int findKthNum(vector<int> &A, int startA, vector<int> B, int startB, int k) {
  // 返回条件,A、B为空,或找第0th数
  if (startA >= A.size()) {
    return B[startB + k - 1];
  }
  if (startB >= B.size()) {
    return A[startA + k - 1];
  }
  if (k == 1) {
    return A[startA] < B[startB] ? A[startA] : B[startB];
  }
  // 开始divide
  if (startA + k / 2 - 1 >= A.size()) {  // 1. A不够k/2长度,则扔掉B
    return findKthNum(A, startA, B, startB + k / 2, k - k / 2);  // k不-1
  }
  if (startB + k / 2 - 1 >= B.size()) {  // B同理
    return findKthNum(A, startA + k / 2, B, startB, k - k / 2);
  }
  // 判断越界后,比较midK
  int midKA = A[startA + k / 2 - 1], midKB = B[startB + k / 2 - 1];
  if (midKA < midKB) {  // 2. A的midK小于B,丢掉A,如1,2,3  4,5,6
    return findKthNum(A, startA + k / 2, B, startB, k - k / 2);
  } else {  // B同理
    return findKthNum(A, startA, B, startB + k / 2, k - k / 2);
  }
}
Loading Disqus comments...
Table of Contents