LeetCode-Algorithms #004 Median Of Two Sorted Arrays
给定两个已经完成排序的整数数组, 数组长度分别为m和n. 找到这两个数组的中位数, 算法的时间复杂度不超过O(log(m+n)).
这两个数组不会都是空的.
1 class Solution { 2 public double findMedianSortedArrays(int[] nums1, int[] nums2) { 3 //创建一个结果数组 4 int[] result; 5 //处理nums1或nums2为空的特殊情况 6 if(nums1==null){ 7 result=nums2; 8 }else if(nums2==null){ 9 result=nums1; 10 } 11 //都非空时把两个数组拼接起来并重新排序 12 else{ 13 result = new int[nums1.length+nums2.length]; 14 System.arraycopy(nums1, 0, result, 0, nums1.length); 15 System.arraycopy(nums2, 0, result, nums1.length, nums2.length); 16 Arrays.sort(result); 17 } 18 //求出并返回中位数 19 int l = result.length; 20 if(l%2==0){ 21 double ans = (double) (result[l/2] + result[l/2 - 1])/2; 22 return ans; 23 } else { 24 double ans = result[l/2]; 25 return ans; 26 } 27 } 28 }
我的想法就是把两个数组拼到一起再重新排序, 但这显然是个笨办法, 但这么做好像时间复杂度上是符合要求的, 因为也只用了一次拼接和两次arraycopy和一次sort
最后虽然顺利通过了, 但显然不是题目设定上想让你采取的方法
回头看LeetCode提供的一种解答思路, 想法上是把两个数组都分割成两部分:
如果我们能够满足上面这两个条件, 即左右两边元素个数相同, 及左侧最大值小于右侧最小值
由于两个原数组本身就是排序完成的, 那么中位数自然就找到了
藉由这种思路, 我们可以知道需要四个变量, i, j表示划分原数组时选择的位置, m, n表示原数组的长度,
以及这四个变量间的关系, 最后用二分查找法找到合适的i,j 找到中位数.
原文的解析实在太长, 这里就只贴上地址和代码:
https://leetcode.com/problems/median-of-two-sorted-arrays/solution/
1 class Solution { 2 public double findMedianSortedArrays(int[] A, int[] B) { 3 int m = A.length; 4 int n = B.length; 5 if (m > n) { // to ensure m<=n 6 int[] temp = A; A = B; B = temp; 7 int tmp = m; m = n; n = tmp; 8 } 9 int iMin = 0, iMax = m, halfLen = (m + n + 1) / 2; 10 while (iMin <= iMax) { 11 int i = (iMin + iMax) / 2; 12 int j = halfLen - i; 13 if (i < iMax && B[j-1] > A[i]){ 14 iMin = i + 1; // i is too small 15 } 16 else if (i > iMin && A[i-1] > B[j]) { 17 iMax = i - 1; // i is too big 18 } 19 else { // i is perfect 20 int maxLeft = 0; 21 if (i == 0) { maxLeft = B[j-1]; } 22 else if (j == 0) { maxLeft = A[i-1]; } 23 else { maxLeft = Math.max(A[i-1], B[j-1]); } 24 if ( (m + n) % 2 == 1 ) { return maxLeft; } 25 26 int minRight = 0; 27 if (i == m) { minRight = B[j]; } 28 else if (j == n) { minRight = A[i]; } 29 else { minRight = Math.min(B[j], A[i]); } 30 31 return (maxLeft + minRight) / 2.0; 32 } 33 } 34 return 0.0; 35 } 36 }
LeetCode-Database #178 Rank Scores
为分数排名, 同分的显示相同的名次, 具体可以看图中的例子
嗯...
简单来说就是
我不会...
看两个答案吧:
SELECT t1.Score, -- 这个思路不错, 用一个自连接获取排名 ( SELECT COUNT(DISTINCT t2.Score)+1 FROM Scores t2 WHERE t1.Score < t2.Score ) AS Rank FROM Scores t1 ORDER BY t1.Score DESC
-- 思路是如果本行分数和上一行不同, 排名就加一
SELECT Score, @rank := @rank + (@prev <> (@prev := Score)) Rank FROM Scores, (Select @rank := 0, @prev := -1) tmp ORDER BY Score desc
点了不少, 不过主要就是这两类写法, 下面那个我确实不太熟悉, 包括@变量 := 值这种写法都忘得差不多了...
SQL这边稍微复杂一点的应用就没什么思路, 借这个机会多练习吧.