文章目录
leetcode之遍历系列算法
1.按键时间最长的键
1.1一次遍历
func slowestKey(releaseTimes []int, keysPressed string) byte {
ans := keysPressed[0]
maxTime := releaseTimes[0]
for i := 1; i < len(keysPressed); i++ {
key := keysPressed[i]
time := releaseTimes[i] - releaseTimes[i-1]
if time > maxTime ||(time == maxTime && key > ans) {
ans = key
maxTime = time
}
}
return ans
}
2.切片最大值及索引
package main
import (
"fmt"
)
func main() {
intArr := []int{3, -4, 93, 8, 12, 29}
maxVal := intArr[0]
maxValIndex := 0
for i := 0; i < len(intArr); i++ {
//从第二个元素开始循环比较,如果发现有更大的数,则交换
if maxVal < intArr[i] {
maxVal = intArr[i]
maxValIndex = i
}
}
fmt.Println(maxVal, maxValIndex)
}
/*
输出:93 2
*/
3.切片最小值及索引
package main
import (
"fmt"
)
func main() {
intArr := []int{3, -4, 93, 8, 12, 29}
maxVal := intArr[0]
maxValIndex := 0
for i := 0; i < len(intArr); i++ {
//从第二个元素开始循环比较,如果发现有更大的数,则交换
if maxVal > intArr[i] {
maxVal = intArr[i]
maxValIndex = i
}
}
fmt.Println(maxVal, maxValIndex)
}
/*
输出:93 2
*/
4.至少是其他数字两倍的最大数
4.1一次遍历
func dominantIndex(nums []int) int {
//小于等于一个元素 直接输出
if len(nums)<=1{
return 0
}
// 初始化 次大为0 最大为索引1的值
lastMax,max:=0,nums[0]
// 最大的下标
maxIndex:=0
// 遍历
for i:=1;i<len(nums);i++{
// 如果num[i]比max大,max变为次大,num[i]变为最大
if nums[i]>max{
lastMax=max
max=nums[i]
maxIndex=i
// 如果比lastMax大 替换
}else if nums[i]>lastMax{
lastMax=nums[i]
}
}
// 判断咯
if max>=lastMax*2{
return maxIndex
}
return -1
}
/*遍历数组分别找到数组的最大值m1和次大值m2
如果m1≥m2×2 成立,则最大值至少是数组其余数字的两倍,此时返回最大值的下标,否则返回 -1。
为了返回最大值的下标,我们需要在计算最大值的同时记录最大值的下标。*/
5.递增的三元子序列
5.1双向遍历
func increasingTriplet(nums []int) bool {
n := len(nums)
if n < 3 {
return false
}
leftMin := make([]int, n) //创建同样长度的切片
leftMin[0] = nums[0]
for i := 1; i < n; i++ {
leftMin[i] = min(leftMin[i-1], nums[i])
}
rightMax := make([]int, n)
rightMax[n-1] = nums[n-1]
for i := n - 2; i >= 0; i-- {
rightMax[i] = max(rightMax[i+1], nums[i])
}
//从第二个元素到倒数第二个元素
for i := 1; i < n-1; i++ {
if nums[i] > leftMin[i-1] && nums[i] < rightMax[i+1] {
return true
}
}
return false
}
func min(a, b int) int {
if a > b {
return b //若b<=a, 则返回b
}
return a
}
func max(a, b int) int {
if b > a {
return b //若a<=b, 则返回a
}
return a
}
/*nums=[2,1,5,0,4,6]
leftMin=[2 1 1 0 0 0]
rightMax=[6 6 6 6 6 6]*/
/*注意:i,j,k不一定是连续的
如果数组 nums 中存在一个下标 i满足 1≤i<n−1,使得在nums[i] 的左边存在一个元素小于 nums[i] ,且在 nums[i] 的右边存在一个元素大于nums[i],则数组 nums 中存在递增的三元子序列。
在 nums[i] 的左边存在一个元素小于nums[i] 等价于在 nums[i] 的左边的最小元素小于 nums[i],在 nums[i] 的右边存在一个元素大于 nums[i] 等价于在 nums[i] 的右边的最大元素大于nums[i],因此可以维护数组 nums 中的每个元素左边的最小值和右边的最大值。
创建两个长度为 nn 的数组 leftMin 和 rightMax,对于0≤i<n,leftMin[i] 表示 nums[0] 到 nums[i] 中的最小值,rightMax[i] 表示 nums[i] 到nums[n−1] 中的最大值。*/