LeetCode题目:4.Median of Two Sorted Arrays
来源:互联网 发布:数据归一化 代码 编辑:程序博客网 时间:2024/06/09 15:09
LeetCode题目:4.Median of Two Sorted Arrays
原题链接:https://leetcode.com/problems/median-of-two-sorted-arrays/description/
解题思路:
由于时间复杂度限制在了 O(log (m+n)),因此不能遍历整个数组。由于是log,因此比较容易想到的是关于二分的算法。
在一个排序好的数组中,查找一个特定值所需的时间为O(log n),类似的,给定一个值x,用二分方法将这个值插入一个排好序的数组a,所需要的时间也为O(log n)。插入的同时,也能知晓给定值x在数组a中排第几位。所以,求中位数可等价于求整个数组中的第n/2大的数。
如题,给定两个排好序的数组a和b,他们的数量分别是n和m,取数组a中的中位数,在数组b中进行二分插入,即可该中位数在整个数组和中的位置,然后和要求的位置比较,如果相等,得到答案。如果不等,舍弃a和b数组的一部分,取另一部分继续上述操作即可。
核心思想:
步骤如下:
设初始目标位置(中位值在总数组的位置)为(m+n)/2。
1.取a或b数组中的某数x(为了尽可能每次筛选足够多的数,x应在大数组中取数,并且使比值相同,即 x位置/大数组数量 = 目标位置/数组总数)。
2.在另一个数组中,二分插入x,得到x在该数组中的位置。
3.求得x在总数组中的位置,与目标位置进行比较。
4.如果相同,该值即为中位值。如果不相同,取两数组各取其中一部分,并修改目标位置,返回1。
代码细节:
1.可能出现二分的时候插入值比整个数组都大或者比整个数组都小
2.直接截取数组可能会花费过多时间,因此修改数组begin和end值来截取数组。
3.若为偶数,有两个中位值,可以计算前,拿出数组中的最小值,这样两个中位值变成了一个中位值和中位值前继。
坑点:
1.其中之一数组为空。
2.二分插入时插入值可能比整个数组都大,要特殊讨论。
3.当总数组只有两个数时,去掉最小值会导致答案错误。
代码:
// 二分查找,查找数字target在nums.begin---nums.end之中的位置// target刚好小于等于nums[return int] int findTargetPositionInNums(vector<int>& nums, int begin, int end, int target) { // 如果区间为空,直接返回 if (begin == end) return begin; int mid = (end + begin) / 2; while (1) { // 区间长度小于1,进行比较 if (end <= begin + 1) if (target > nums[mid]) return end; else return begin; // nums[mid - 1] <= nums[mid] < target if (target > nums[mid]) begin = mid + 1; // nums[mid - 1] < target <= nums[mid],返回结果 else if (target > nums[mid - 1]) return mid; // target <= nums[mid - 1] <= nums[mid] else end = mid; mid = (end + begin) / 2; }}// 根据总数返回中位值,其中value1 < value2double getMedian(int value1, int value2, bool isEven) { return isEven ? (double)(value1 + value2) / 2 : value2;}double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int sumSize = nums1.size() + nums2.size(); // 总数 bool isEven = sumSize % 2 == 0; // 判断中位数数量 // 当数量太小 if (sumSize <= 2) { nums1.insert(nums1.end(), nums2.begin(), nums2.end()); if (isEven) return (double)(nums1[0] + nums1[1]) / 2; return nums1[0]; } // 当其中一个数组为空 if (nums1.empty()) return getMedian(nums2[nums2.size() / 2 - 1], nums2[nums2.size() / 2], isEven); else if (nums2.empty()) return getMedian(nums1[nums1.size() / 2 - 1], nums1[nums1.size() / 2], isEven); // 正常数组 // 如果是偶数,去掉最小值,使中位数只有一个 if (isEven) { if (nums1[0] < nums2[0]) nums1.erase(nums1.begin()); else nums2.erase(nums2.begin()); sumSize--; } int begin1 = 0; int end1 = nums1.size(); int begin2 = 0; int end2 = nums2.size(); // 用于递归的值 int medianPosInSum = sumSize / 2 + 1; // 中位数在总数组中第几大,一开始为sumSize/2+1 int posInBig; // 某数在大数组中的位置 int posInSmall; // 某数在小数组中的位置 int posInSum; // 某数在总数组中的位置 int isInNums1; // 判断最后得到的中位值在nums1还是nums2 while (1) { if (end1 - begin1 > end2 - begin2) { // 从大数组中取一个可能的位置,为了降低时间复杂度,取比例位置 posInBig = (float)medianPosInSum / sumSize * (end1 - begin1) + begin1; // 在小数组中找到相应的位置 posInSmall = findTargetPositionInNums(nums2, begin2, end2, nums1[posInBig]); // 求出该数在总数组的位置 posInSum = (posInBig - begin1 + 1) + (posInSmall - begin2); // 将posInSum和medianPosInSum比较 // posInSum < medianPosInSum,砍掉左半部分 if (posInSum < medianPosInSum) { medianPosInSum -= posInSum; begin2 = posInSmall; begin1 = posInBig + 1; } // posInSum > medianPosInSum,砍掉右半部分 else if (posInSum > medianPosInSum) { end2 = posInSmall; end1 = posInBig; } // posInSum == medianPosInSum,得到结果,跳出循环 else { isInNums1 = true; break; } } // 对称 else { posInBig = (float)medianPosInSum / sumSize * (end2 - begin2) + begin2; posInSmall = findTargetPositionInNums(nums1, begin1, end1, nums2[posInBig]); posInSum = (posInBig - begin2 + 1) + (posInSmall - begin1); if (posInSum < medianPosInSum) { medianPosInSum -= posInSum; begin1 = posInSmall; begin2 = posInBig + 1; } else if (posInSum > medianPosInSum) { end1 = posInSmall; end2 = posInBig; } else { isInNums1 = false; break; } } } // 求出中位值和中位值的前一个值 int median = isInNums1 ? nums1[posInBig] : nums2[posInBig]; int preMedian = isInNums1 ? max(nums1[posInBig - 1], nums2[posInSmall - 1]) : max(nums2[posInBig - 1], nums1[posInSmall - 1]); return getMedian(preMedian, median, isEven);}
- LeetCode 题目 4. Median of Two Sorted Arrays
- LeetCode题目:4.Median of Two Sorted Arrays
- [LeetCode]4.Median of Two Sorted Arrays
- LeetCode 4. Median of Two Sorted Arrays
- LeetCode --- 4. Median of Two Sorted Arrays
- [Leetcode] 4. Median of Two Sorted Arrays
- [LeetCode]4.Median of Two Sorted Arrays
- 【leetcode】4. Median of Two Sorted Arrays
- Leetcode-4.Median of Two Sorted Arrays
- LeetCode-4.Median of Two Sorted Arrays
- Leetcode 4. Median of Two Sorted Arrays
- leetcode 4. Median of Two Sorted Arrays
- LeetCode 4. Median of Two Sorted Arrays
- Leetcode 4. Median of Two Sorted Arrays
- Leetcode 4. Median of Two Sorted Arrays
- [leetcode]4. Median of Two Sorted Arrays
- LeetCode-4.Median of Two Sorted Arrays
- [LeetCode]4. Median of Two Sorted Arrays
- Arpa's weak amphitheater and Mehrdad's valuable Hoses CodeForces
- Servlet总结四(过滤器的使用)
- python 设计模式实现
- 《JavaScript高级程序设计》知识概要(p1~9)
- TCP三次握手四次挥手
- LeetCode题目:4.Median of Two Sorted Arrays
- 训练总结
- 3875: [Ahoi2014&Jsoi2014]骑士游戏
- 日记—9.17
- Java Succinctly Part 2.azw3
- 前端一条线了解
- camera MCLK配置错误造成 i2c不通的 修改方法
- Linux下Tomcat的安装与部署
- 互联网常见的层次架构