leetcode感想
来源:互联网 发布:淘宝自动充值平台利润 编辑:程序博客网 时间:2024/06/14 07:12
首次刷leetcode。写完两题easy和一题medium后感觉题目偏容易,准备挑战一下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
第一反应是,这题不是重排序成一个数组然后取下标中间值就行了么,so easy。
然而注意到时间复杂度要求在O(log(m+n))以内,这题就有意思了。因为重新排序至少也要花费O(m+n)的时间,而要求的时间复杂度就限制了重新排序的可能。
想了一个多小时,发现同时丢掉中位数左边和右边的N个数对中位数是没有影响的,于是决定用二分法递归地来解决这个问题。思路是不停的丢弃中位数左右边的n个数,直到有一个数组里只有一个数,开始计算中位数,运算结束。
另外在跑测试用例的时候遇到了一些特殊情况,又增加了一些特殊情况的判断。最终得到代码如下:
double median2c(int* nums, int numsSize){ if(numsSize%2==0) { return (nums[numsSize/2-1]+nums[numsSize/2])/2.0; } else if(numsSize%2==1) { return (double)nums[numsSize/2]; } return -1;}double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size) { if(nums1Size==0) return median2c(nums2, nums2Size); if(nums2Size==0) return median2c(nums1, nums1Size); int cutlen; if(nums1Size%2 == 0 && nums2Size%2 == 0) { if(nums1[nums1Size/2-1]<nums2[nums2Size/2-1] && nums1[nums1Size/2]>nums2[nums2Size/2]) return (nums2[nums2Size/2-1]+nums2[nums2Size/2])/2.0; if(nums1[nums1Size/2-1]>nums2[nums2Size/2-1] && nums1[nums1Size/2]<nums2[nums2Size/2]) return (nums1[nums1Size/2-1]+nums1[nums1Size/2])/2.0; } if(nums1Size==1 && nums2Size==1) { return (nums1[0]+nums2[0])/2.0; } else if(nums1Size==1) { if(nums2Size%2 == 0) { if(nums1[0]<=nums2[nums2Size/2-1]) return nums2[nums2Size/2-1]; else if(nums1[0]>=nums2[nums2Size/2]) return nums2[nums2Size/2]; else if(nums1[0]>nums2[nums2Size/2-1] && nums1[0]<nums2[nums2Size/2]) return nums1[0]; } else if(nums2Size%2 == 1) { if(nums1[0]<=nums2[nums2Size/2-1]) return (nums2[nums2Size/2-1]+nums2[nums2Size/2])/2.0; else if(nums1[0]>=nums2[nums2Size/2+1]) return (nums2[nums2Size/2]+nums2[nums2Size/2+1])/2.0; else if(nums1[0]>nums2[nums2Size/2-1] && nums1[0]<nums2[nums2Size/2+1]) return (nums1[0]+nums2[nums2Size/2])/2.0; } } else if(nums2Size==1) { return findMedianSortedArrays(nums2, nums2Size, nums1, nums1Size); } else { cutlen = (nums1Size/2 > nums2Size/2) ? nums2Size/2 : nums1Size/2; if(median2c(nums1,nums1Size) > median2c(nums2,nums2Size)) { nums2 = nums2 + cutlen; } else if(median2c(nums1,nums1Size) < median2c(nums2,nums2Size)) { nums1 = nums1 + cutlen; } else if(median2c(nums1,nums1Size) == median2c(nums2,nums2Size)) { return median2c(nums1,nums1Size); } nums1Size = nums1Size - cutlen; nums2Size = nums2Size - cutlen; // return findMedianSortedArrays(nums1, nums1Size, nums2, nums2Size); } return findMedianSortedArrays(nums1, nums1Size, nums2, nums2Size);}
编写过程耗时超过3个小时。但毕竟是我第一次在实际问题中用递归思想将一个O(n)复杂度的算法降为了O(log(n)),心里还是挺美滋滋的。毕竟几年前在算法导论上看到分治法、快速排序等算法时还只能感叹前人的智慧。提交成功之后点击more details,发现自己只超过了77%的人,也就是说还有23%的人有更快的算法。于是我抱着学习的心态点进了速度最快的代码——下面转折来了。“最快“的算法使用的居然是O(m+n)复杂度的重新排序方法!也就是本博客一开始说的so easy的方法。
当时就有点崩溃,点开其他各个运行速度的代码查看,无一例外全部是O(m+n)。我转念一想,返回了提交页面重新提交了我的代码。提交的第二次居然只超过了44%的人。而提交到第五次的时候,也就是写这篇博客之前,居然获得了这样的结果:??WTF?这算是leetcode颁发的安慰奖吗?
不管怎么样,通过这次刷题,得到了如下结论:
1.leetcode是一个适合练习编程语言而不是算法的地方。毕竟不合算法要求的代码提交也能通过,并且也有一定几率获得较好的运行时间结果。
2.代码的运行时间是在一定分布内随机波动的。不要太在意这个扯淡的submission detail。
3.有没有人能推荐个更靠谱点算法练习学习的网站?
- LeetCode感想
- leetcode感想
- leetcode-easy OJ感想
- leetcode刷题感想
- 感想
- 感想!
- 感想
- 感想
- 感想
- 感想!
- 感想
- 感想
- 感想
- 感想
- 感想
- 感想
- 感想
- 感想
- Macbook Pro搭建PHP开发环境
- Survey of single-target visual tracking methods based on online learning 翻译
- MySQL 创建数据表
- 神器Vim之命令介绍
- 分类loss cross-entropy
- leetcode感想
- RabbitMQ Server安装及显示管理界面_Installing on Windows
- 使用sizeof获取类的大小
- Linux学习总结
- 人脸检测——人脸肤色相似度计算流程
- 整数二进制位中1的个数【每日一题】
- localStorage使用总结
- oracle数据删除恢复
- Docker安装和常用命令及构建镜像