求递增数列中所有A[i]=i的元素(阿里巴巴2013笔试题)
来源:互联网 发布:2007年网络流行歌曲 编辑:程序博客网 时间:2024/06/07 05:21
求递增数列中所有A[i]=i的元素
阅读更多博客,请访问博主的个人网站 点击访问网站
题意描述
给定一个排好升序的数组A[1]、A[2]、……、A[n],其元素两两不相等。请设计一高效的算法找出中间所有A[i] = i的下标。并分析其复杂度。
思路分析
该题目有两个重要的条件:
1. 排好升序的数组
2. 元素两两不相等
我们根据以上两个已知条件可以得出以下定理:
定理1:在递增序列中A中,对于A的所有元素A[i],如果满足A[i] = i, 则他们组成一个连续的序列。
对于定理1这里不作证明,只给出两个例子来阐述定理的意义。
1. 已知A中满足条件的元素只有A[i],A[j],A[k]三个,且i < j < k,那么我们根据定理1就可以断言:i + 1 = j 且 j + 1 = k。
2. 已知A中有元素A[i] = i, A[i + 1] = i + 1,但是A[i + 2] ≠ i + 2,那么A[i + 2]后面的元素也不会再有满足条件的元素了。同理,若A[i - 1] ≠i - 1,那么可以推出A[i - 1]前面也不会再有满足条件的元素了。
算法设计
由定理1知,所有满足条件的元素挨在一块组成一个连续数列。我们的算法就是找出这个数列的左边界和右边界。
1. 二分查找左边界,即满足 A[i] = i 且 A[i - 1] < i - 1的位置。
2. 二分查找右边界,即满足A[i] = i 且A[i + 1] > i + 1。
3. 左边界到右边界之间的即为满足条件的元素。
代码实现(python)
class Solution: def getLeftBound(self, a): low = 0 high = len(a) - 1 while low <= high: mid = (low + high) / 2 if a[mid] == mid and (mid == 0 or a[mid - 1] != mid - 1): return mid elif a[mid] < mid: low = mid + 1 elif a[mid] > mid: high = mid - 1 else: high = mid - 1 return -1 def getRightBound(self, a): low = 0 high = len(a) - 1 while low <= high: mid = (low + high) / 2 if a[mid] == mid and (mid == len(a) - 1 or a[mid + 1] != mid + 1): return mid elif a[mid] < mid: low = mid + 1 elif a[mid] > mid: high = mid - 1 else: low = mid + 1 return -1 def getAns(self, a): l = self.getLeftBound(a) r = self.getRightBound(a) return a[l : r + 1]s = Solution()a = [-1, 0, 2, 3, 4, 5, 6, 9]print s.getAns(a)
复杂度分析(时间)
- 代码中getLeftBound()和getRightBound()都是二分查找的过程,复杂度为O(logn)
- 最后返回满足条件的元素 的操作,复杂度为O(n)
1 0
- 求递增数列中所有A[i]=i的元素(阿里巴巴2013笔试题)
- 搜狗2014年笔试题-两递增数组A和B,求A[i]+B[j]中前k个最小值(Java)
- 搜狗2014年笔试题-两递增数组A和B,求A[i]+B[j]中前k个最小值(Java)
- 求一个数组(a(i,j))中元素相减的最大值,且i<=j
- 搜狗2014年笔试题-两递增数组A和B,求A[i]+B[j]中前k个最小值
- 求数组中除第i个外的所有其他数组元素的乘积
- i++ ++i 的笔试题
- VC 中关于a=(i++)+(++i)+(i++)的分析
- 从一给定的顺序表L中删除下标i--j(i<=j,包括i、j)的所有元素,假定i、j都是合法的
- 对给定正整数数列A进行重新排序,使得数列A满足所有的A[i]*A[i+1]都是4的倍数。
- boj 1347 简单数组问题 在一个二维数组中 a[i][j]=a[i][j]+a[i-1][j]+a[i][j-1]-a[i-1][j-1] 则a[i][j]为i j位置左上侧所有元素之和
- 中位数------求数组中第i小的元素
- 求 數組中元素a[i]: 大於或等於其前所有的數,小於或等於其後的所有的數
- 给定一个整数数组,1≤a [i]≤n(n =数组的大小),一些元素出现两次,其他出现一次 查找在该数组中出现两次的所有元素
- 求一个数组中a[0...i-1] 离a[i]最接近的值
- 求第i小的元素(2)
- 求第i小的元素
- 求第i小的元素
- 让Linux系统启动过程自动运行自己编写的脚本
- Pod在墙内
- Activity类
- 双检查加锁优化模式
- servlet3 文件上传
- 求递增数列中所有A[i]=i的元素(阿里巴巴2013笔试题)
- 如何提升网站的性能?
- jQuery自学教程(一)
- start from here
- android 6.0不能在eclipse下生成R文件的问题
- google输入法 日文 [CapsLock]キー ひらがな⇔直接入力の設定
- DOM
- #android#android studio 使用cardview
- 怎样在win7中 安装Tomcat7.0