剑指offer|6.寻找峰值
Posted MicroFrank
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer|6.寻找峰值相关的知识,希望对你有一定的参考价值。
0.寻找峰值
关键点:
- 返回任意一个峰值的下标即可
- nums[-1]=nums[n]=负无穷
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2
1.傻瓜编程(纯属玩乐)
class Solution
public:
int findPeakElement(vector<int>& a)
int n=a.size();
if(n==1)
return 0;
if(n==2)
if(a[0]>a[1])
return 0;
else
return 1;
for(int i=1;i<n-1;i++)
if(a[0]>a[1]) return 0;
if(a[n-2]<a[n-1]) return n-1;
if(a[i]>a[i-1]&&a[i]>a[i+1]) return i;
return -1;
;
2.二分
看到题目要求的时间复杂度是o(logN),优先考虑二分查找,但是二分查找的前提似乎要是有序的,其实通过这题我们也能发现,使用二分法不一定要求有序,只要求可以确定答案一定会出现在其中一边即可
int findPeakElement(int* nums, int numsSize)
int left=0,right=numsSize-1;
while(left<right)//
int mid=left+(right-left)/2;
if(nums[mid+1]>=nums[mid])
left=mid+1;//
else if(nums[mid+1]<nums[mid])
right=mid;//
return left;
关键点:
- 因为mid=(left+right)/2这整数除法的特性,向下取整,只要数组元素个数大于等于2,mid+1下标一定存在(当数组元素等于1的时候,left==right,不会进该循环) , 而mid-1下标不一定存在,mid-1>=0减少边界讨论的情况
- 注意[left,right] 的范围就是答案所在的区域范围
- 最后left==right时定位到峰值的位置
LeetCode 字符串的排列全排列问题(剑指offer38)
func permutation(s string) []string {
//思路:使用寻找下一个增长序列(同官方解题)
//步骤:1.升序排序 2.依次使用寻找下一个序列查找下一个符合条件的序列 3.返回结果
bs := []rune(s)
l := len(bs)
if l == 0 || l > 8 {
//panic("参数长度异常")
return []string{}
}
sort.Slice(bs, func (a, b int) bool {
return bs[a] < bs[b]
})
list := make([]string, 0, l)
for {
list = append(list, string(bs))
if !nextPermutation(bs) {
break
}
}
return list
}
func nextPermutation(bs []rune) bool {
l := len(bs)
//左边起始查找位,按照之前置换原则,只有右数比左数大才能有下一个更大序列
lIdx := l - 2
for lIdx >= 0 && bs[lIdx] >= bs[lIdx+1] {
lIdx--
}
if (lIdx < 0) {
return false
}
//从最右边开始找,第一个比lIdx大的数即为,最小的大值
rIdx := l - 1
for rIdx >= 0 && bs[lIdx] >= bs[rIdx] {
rIdx--
}
bs[lIdx], bs[rIdx] = bs[rIdx], bs[lIdx]
//按照前面的置换原则,将后面的序列,反转即为新的升序[)
reverse(bs[lIdx+1:])
return true
}
func reverse(list []rune) {
for i, l := 0, len(list); i < l/2; i++ {
list[i], list[l-1-i] = list[l-1-i], list[i]
}
}
以上是关于剑指offer|6.寻找峰值的主要内容,如果未能解决你的问题,请参考以下文章
算法---- Leetcode剑指offer-Java版题解
算法---- Leetcode剑指offer-Java版题解