LeetCode 4
Posted 一只狐狸scse
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 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
Solution:
static const auto speedup = [](){ ios::sync_with_stdio(false); cin.tie(nullptr); return nullptr; }(); class Solution { public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int l1 = nums1.size(), l2 = nums2.size(); if (l1 > l2){ vector<int> temp = nums1; nums1 = nums2; nums2 = temp; int temp_num = l1; l1 = l2; l2 = temp_num; } int iMax = l1, iMin = 0, h = (l1 + l2 + 1) / 2, i = 0, j = 0; while (iMin <= iMax){ i = (iMax + iMin) / 2, j = h - i; if (i > iMin && nums1[i-1] > nums2[j]){ iMax = i - 1; }else if (i < iMax && nums2[j-1] > nums1[i]){ iMin = i + 1; }else{ int left = 0, right = 0; if (i == 0){ left = nums2[j-1]; }else if (j == 0){ left = nums1[i-1]; }else{ left = nums1[i-1] > nums2[j-1] ? nums1[i-1] : nums2[j-1]; } if ((l1 + l2) % 2 == 1){ return left; } if (i == l1){ right = nums2[j]; }else if (j == l2){ right = nums1[i]; }else{ right = nums1[i] < nums2[j] ? nums1[i] : nums2[j]; } return (left + right) / 2.0; } } return 0; } };
1. 思路简述
整体的思路是二分查找。首先假设数组A是较短的那个数组,数组B是较长的那个数组,我们要找的是这两个数组的分割点i j,分割点要满足如下几个因素:
1. 分割点左边两数组的任意元素均小于分割点右边两数组的任意元素
2. 分割点左边的元素的个数之和等于右边的元素个数之和: j = (l1 + l2 + 1) / 2 - i .
所以:
1. 按照首先二分定位A的中间点作为i,计算j
2.查看i是否符合要求
2.1 如不符合要求则更新iMax或iMin进行下一次二分
2.2 如果符合要求,计算left和right
2.2.1 left为数组两部分左边的最大值。当i == 0时(A整个数组都大于B,整个A放在右半边)left == B[j-1];当j == 0时(B整个数组都大于A)left == A[i-1];正常情况下,选出left == max(A[i-1], B[j-1])。在这里,如果(l1 + l2) % 2 == 1,程序结束,返回left。
2.2.2 right为数组两部分右边的最小值。当i == l1时(A整个数组都小于B,整个A放在左半边)right == B[j];当j == l2时(B整个数组都小于A)right == A[i];正常情况下,选出right == min(A[i], B[j])
2. 改进方式
2.1 速度改进
static const auto speedup = [](){ ios::sync_with_stdio(false); cin.tie(nullptr); return nullptr; }();
加入这一段代码可以让代码提速很多(From Top70% to Top30%),原因是:
std::ios::sync_with_stdio(false);
这个函数是一个“是否兼容stdio”的开关,C++为了兼容C,保证程序在使用了std::printf和std::cout的时候不发生混乱,将输出流绑到了一起。
cin,cout之所以效率低,是因为先把要输出的东西存入缓冲区,再输出,导致效率降低,而这段语句可以来打消iostream的输入 输出缓存,可以节省许多时间,使效率与scanf与printf相差无几,还有应注意的是scanf与printf使用的头文件应是stdio.h而不是 iostream。
cin.tie(nullptr);
tie是将两个stream绑定的函数,空参数的话返回当前的输出流指针。
PS. NULL & nullptr
在C++中指针必须有明确的类型定义。但是将NULL定义为0带来的另一个问题是无法与整数的零区分。因为C++中允许有函数重载,所以可以试想如下函数定义情况:
void func(int data); void func(char* data);
那么在传入NULL参数时,编译器将无法确定到底使用哪个函数定义,造成编译时错误。nullptr在C++11被引入用于解决这一问题,nullptr可以明确区分整型和指针类型,能够根据环境自动转换成相应的指针类型,但不会被转换为任何整型,所以不会造成参数传递错误。
2.2 某一种写法
if(nums1.size() < nums2.size()) { return findMedianSortedArrays(nums2, nums1); }
以上是关于LeetCode 4的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段