代码随想录算法训练营Day01 | 704.二分查找、27.移除元素

120 阅读2分钟

数组基础理论

数组是存放在连续内存空间上的相同类型数据的集合。

LeetCode题目

704.二分查找

题目链接:Binary Search - LeetCode

解法一

定义 target 在一个左闭右闭区间里[left, right]

注意区间边界处理,代码如下:

func binarySearch(nums []int, target int) int {
	left := 0
	right := len(nums) - 1
	for left <= right {
		// 避免大数越界,两int相加可能超过int取值范围,等效于(left + right) / 2
		middle := left + (right-left)/2
		if nums[middle] > target {
			right = middle - 1
		} else if nums[middle] < target {
			left = middle + 1
		} else {
			return middle
		}
	}
	return -1
}

解法二

定义 target 在一个左闭右开区间里[left, right)

同注意区间边界处理,与解法一对照理解,代码如下:

func search(nums []int, target int) int {
	left := 0
	right := len(nums)
	for left < right {
		middle := left + (right-left)/2
		if nums[middle] > target {
			right = middle
		} else if nums[middle] < target {
			left = middle + 1
		} else {
			return middle
		}
	}
	return -1
}

27.移除元素

题目链接:Remove Element - LeetCode

解法一

快慢指针法

  • 初始化慢指针 slow
  • 通过 for 循环移动快指针 fast
  • 找到不等于 val 的元素
  • 将其写入 slow 指向的位置,并将 slow 后移一位

代码如下:

func removeElement(nums []int, val int) int {
	slow := 0
	for fast := 0; fast < len(nums); fast++ {
		if nums[fast] == val {
			continue
		}
		nums[slow] = nums[fast]
		slow++
	}
	return slow
}

解法二

相向双指针法

  • 从左向右寻找 val,从右向左寻找非 val,找到时交换位置,目的是将左侧 val 全覆盖掉
  • 各自找到后开始覆盖,覆盖后继续寻找

代码如下:

func removeElement(nums []int, val int) int {
	left := 0
	right := len(nums) - 1
	for left <= right {
		for left <= right && nums[left] != val {
			left++
		}
		for left <= right && nums[right] == val {
			right--
		}
		if left < right {
			nums[left] = nums[right]
			left++
			right--
		}
	}
	return left
}

总结

  1. 根据左闭右开,左闭右闭两种区间规则写出来的二分法
  2. 双指针法