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的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段4——cli的终端命令大全

web代码片段

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段

LEETCODE 003 找出一个字符串中最长的无重复片段

Leetcode 763 划分字母区间

Xcode 4.6 的备份代码片段