leetcode题解日练--2016.9.17
来源:互联网 发布:nemo软件 编辑:程序博客网 时间:2024/06/01 09:40
平常心
今日题目:
1、两个有序数组的中位数
2、找到两个数组中最小的k对最小和
今日摘录:
天上浮云如白衣,斯须改变如苍狗。——杜甫《何叹》
4. Median of Two Sorted Arrays | Difficulty: Hard
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)).
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
tag:数组|二分|分治
题意:先给定两个数组,求它们的中位数,复杂度O(log (m+n)).
思路:
1、找中位数就是在两个数组中各自找到一个i、j元素作为分割线,分割线需要满足三个方程:
i+j=(nums1.size()+nums2.size()+1)/2 —> 二分去搜索i.j=(nums1.size()+nums2.size()+1)/2-i
nums1[i-1]<=nums2[j] (前提i-1和j不越界)
nums2[j-1]<=nums1[i] (前提j-1和i不越界)
当找到满足条件的i,j时候就返回,
否则如果nums1[i-1]
class Solution {public: double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int len1 = nums1.size(),len2 = nums2.size(); if(len1>len2) return findMedianSortedArrays(nums2,nums1); int halfLen = (len1+len2+1)/2; int iLeft = 0,iRight = len1; double maxLeft = INT_MIN,minRight = INT_MAX; while(iLeft<=iRight) { int i = iLeft+(iRight-iLeft)/2; int j = halfLen-i; if(j>0 && i<len1 && nums1[i]<nums2[j-1]) iLeft = i+1; else if(i>0 && j<len2 && nums2[j]<nums1[i-1]) iRight = i-1; else { if(i==0) maxLeft = nums2[j-1]; else if(j==0) maxLeft = nums1[i-1]; else maxLeft = max(nums1[i-1],nums2[j-1]); if((len1+len2)%2==1) return maxLeft; else if(i==len1) minRight = nums2[j]; else if (j==len2) minRight = nums1[i]; else minRight = min(nums1[i],nums2[j]); return (maxLeft+minRight)/2; } } return -1; }};
结果:29ms
2、一样的思想,转换成找两个数组中的第K大数。
这里偶数个数的情况下要调用两次函数,可以改成加如一个标志位来做。
class Solution {public: double findLargestK(const vector<int>&nums1,const vector<int>& nums2,int len1,int len2,int k) { int iLeft = 0,iRight = len1; double res =0; while(iLeft<=iRight) { int i = iLeft+(iRight-iLeft)/2; int j = k-i; if(j>len2 ||j>0 && i<len1 && nums1[i]<nums2[j-1]) iLeft = i+1; else if(i>len1 || i>0 && j<len2 && nums2[j]<nums1[i-1]) iRight = i-1; else { if(i==0) res = nums2[j-1]; else if(j==0) res = nums1[i-1]; else res = max(nums1[i-1],nums2[j-1]); return res; } } return -1; } double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { int len1 = nums1.size(),len2 = nums2.size(); if(len1>len2) return findMedianSortedArrays(nums2,nums1); int totalLen = len1+len2; if(totalLen%2==1) return findLargestK(nums1,nums2,len1,len2,totalLen/2+1); else return (findLargestK(nums1,nums2,len1,len2,totalLen/2)+ findLargestK(nums1,nums2,len1,len2,totalLen/2+1))/2; }};
结果:62ms
373. Find K Pairs with Smallest Sums | Difficulty: Medium
You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.
Define a pair (u,v) which consists of one element from the first array and one element from the second array.
Find the k pairs (u1,v1),(u2,v2) …(uk,vk) with the smallest sums.
Example 1:
Given nums1 = [1,7,11], nums2 = [2,4,6], k = 3
Return: [1,2],[1,4],[1,6]
The first 3 pairs are returned from the sequence:
[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
Example 2:
Given nums1 = [1,1,2], nums2 = [1,2,3], k = 2
Return: [1,1],[1,1]
The first 2 pairs are returned from the sequence:
[1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
Example 3:
Given nums1 = [1,2], nums2 = [3], k = 3
Return: [1,3],[2,3]
All possible pairs are returned from the sequence:
[1,3],[2,3]
tag:堆
题意:找到两个数组中最小的k对最小和
思路:
1、建立一个最小堆,这样每次堆顶都是我们需要找的一对数,但是现在不是对一个数字进行排序,而是对一对数字的和进行排序,因此需要自定义一个比较函数,自己定义一个堆处理成对的数据结构。
每次我们取出了(i,j)对元素之后,接下来按理需要放进去(i+1,j)和(i,j+1)。但是在(i+1,j-1)判断的时候同样会加入(i+1,j),这样就重复了。那怎么解决呢?
除了第一行元素加入右边和下面的元素之外,其他元素都只加入下面的元素。
class Solution {public: vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) { vector<pair<int ,int> > res; if (nums1.empty() || nums2.empty() || k <= 0) return res; //创建一个堆 auto compare = [&nums1,&nums2](pair<int,int> a,pair<int,int>b){ return nums1[a.first]+nums2[a.second] > nums1[b.first]+nums2[b.second]; }; priority_queue< pair<int,int>,vector<pair<int ,int> >, decltype(compare) > heap(compare); heap.emplace(0,0); while(k-- && !heap.empty()) { auto index = heap.top(); heap.pop(); res.emplace_back(nums1[index.first],nums2[index.second]); if(index.first+1<nums1.size()) heap.emplace(index.first+1,index.second); if(index.first==0 && index.second+1<nums2.size()) heap.emplace(index.first,index.second+1); } return res; }};
结果:16ms
- leetcode题解日练--2016.9.17
- leetcode题解日练--2016.9.01
- leetcode题解日练--2016.9.12
- leetcode题解日练--2016.9.14
- leetcode题解日练--2016.6.17
- leetcode题解日练--2016.7.17
- leetcode题解日练--2016.6.16
- leetcode题解日练--2016.6.19
- leetcode题解日练--2016.6.18
- leetcode题解日练--2016.6.20
- leetcode题解日练--2016.6.21
- leetcode题解日练--2016.6.22
- leetcode题解日练--2016.6.23
- leetcode题解日练--2016.6.24
- leetcode题解日练--2016.6.25
- leetcode题解日练--2016.6.26
- leetcode题解日练--2016.6.27
- leetcode题解日练--2016.6.28
- 面试算法--if语句中使用赋值语句
- Effective Java学习笔记 第60条: 优先使用标准的异常
- getParameter和 getAttribute的区别?
- Date & Time Format
- Orcal数据库的表结构转换成mysql数据库的表结构
- leetcode题解日练--2016.9.17
- Android ListView复用机制详解
- python核心编程学习笔记-2016-09-17-02-数据库编程(二)
- 安卓中画笔工具的初步认识
- Android 图片获取:从服务器下载与缓存本地
- 猿辅导2017校园招聘笔试题 求和为0的最长连续子数组
- 信息摘要算法——MessageDigest类
- Linux基础知识
- php史上最全的正则表达式,供学习参考