概述
一:二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
示例 1:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
示例 2:
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
func search(nums []int, target int) int {
/**
分析思路:
首先看题意:有序查找,可以用二分,极端情况考虑只传一个的情况
**/
//开始
//left right为左右两个
n := len(nums)
left := 0
//数组下标为n-1
right := n - 1
//1:先写循环主干
for left <= right {
mid := (right + left)/2
if nums[mid] == target {
return mid
} else if nums[mid] > target {
//在右边
right = mid - 1
} else {
left = mid + 1
}
}
return -1
}
二:搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
示例 1:
输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:
输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:
输入: nums = [1,3,5,6], target = 7
输出: 4
func searchInsert(nums []int, target int) int {
/**
思路分析:
第一部分就是个二分查找
第二部分,不存在就插入到指定位置,每一次和中间值比较有3种情况,=,>, <,当进行到最后一轮时,如果大于,那mid+1就是他的插入位置,小于就是mid-1
**/
//开始
n := len(nums)
left := 0
right := n -1
//记录要插入的位置
tag := 0
//1:先写主体循环
for left <= right {
mid := (left + right) / 2
fmt.Println(nums[mid],mid, left, right)
if nums[mid] == target {
return mid
} else if target > nums[mid] {
left = mid + 1
//右边插入需要mid+1
tag = left
} else {
right = mid -1
//左边插入就是在mid
tag = mid
}
}
return tag
}
三:最长增长子序列
给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。
子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
示例 1:
输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
示例 2:
输入:nums = [0,1,0,3,2,3]
输出:4
示例 3:
输入:nums = [7,7,7,7,7,7,7]
输出:1
思路在代码注释中(动态规划解法)
func lengthOfLIS(nums []int) int {
/**
思路分析:
这里需要求解的是,到终点最长的子序列,如果我们能记录下前面每个点到终点的最长值,最终筛选出最长的一个就可以了。所以可以理解为,到1最长的值,到2最长的值。。。。到n最长的值。那么怎么获取每一个最大的值那,到i的最大值取决于,到前面i-1的最大值,与到i的最大值,哪个大就取哪个,所以每次有一个比较,筛选最大值。这样就可以通过动态规划来解决了。
**/
//开始
n := len(nums)
if n == 0 {
return 0
}
//定义dp
var dp = make([]int, n)
//1:先写循环主体
for i:=0; i < n; i++ {
//因为dp[i]刚开始遍历到i,还么有赋值,所以默认是1
dp[i] = 1
//j从0开始直到匹配到最后一个,也就是i
for j:=0; j < i; j++ {
//nums[j] < nums[i],说明这俩符合递增
if nums[i] > nums[j] {
//这一步比较难理解:
//我们先思考dp[i]等于什么,当刚进入这一层时,dp[i] = 1,初始值.
//然后思考dp[j]等于什么,如果此刻 j = 2, 就是思考dp[2]等于什么,当i = 3时,dp[2]就是上一轮的最大值,举个例子: 1,2,3 这里dp[2] = 3最长距离,并且nums[j] = nums[2] = 3目前最大,所以nums[i]=nums[3] > 3,这个最长序列就可以加1,所以只需要比较目前最大,和当前dp[i]哪个大,取哪个就可以了。
dp[i] = max(dp[i], dp[j]+1)
}
}
}
//返回dp中最大的一个,这里每一次要拿最新值和最大值比较
maxNum := dp[0]
for i:= 1; i< len(dp); i++{
maxNum = max(dp[i], maxNum)
}
return maxNum
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
最后
以上就是多情滑板为你收集整理的GO算法-二分法的全部内容,希望文章能够帮你解决GO算法-二分法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复