1. 数组理论基础
-
数组在计算机内存上是连续存储的同类型数据集合
-
可以迅速的通过下标索引查找到数据【n(0)】
-
索引都从0开始
-
增添麻烦
- 需要移动该索引后续所有元素
- 数组不存在删除,只能用后续的元素进行覆盖操作
-
二维数组在内存的空间地址也是连续的
func main() { arr := [][]int8{ // 因为地址是16进制的, 默认int是int64;因此这里用int8,便于观察结果 {1, 2, 3}, *{4, 5, 6},* } for i := range arr { for j := range arr[i] { fmt.Printf("arr[%d][%d] value is %v,\\taddress is %v\\n", i, j, arr[i][j], &arr[i][j]) } } }
-
运行结果
$ go run . arr[0][0] value is 1, address is 0xc00000a0b8 arr[0][1] value is 2, address is 0xc00000a0b9 arr[0][2] value is 3, address is 0xc00000a0ba arr[1][0] value is 4, address is 0xc00000a0bb arr[1][1] value is 5, address is 0xc00000a0bc arr[1][2] value is 6, address is 0xc00000a0bd
-
从结果中不难看出地址的确是连续的
-
2. 二分查找
关联 leetcode 704. 二分查找
- 启用二分法的思路
- 数组有序
- 无重复元素
- 如果有重复元素,则可能查找结果不唯一
- 练习要点:二分区间的设置
- 处理一定是未知的区间(这里也就能推导出是否要包含mid的值了)
- 方法一:左闭右闭区间
- 保证下一个迭代区间符合该区间定义
- 即左右都是target可能存在范围
- 右区间初始化是 数组的最大索引值
- 方法二:左闭右开区间
- 保证下一个迭代区间符合该区间定义
- 即只有左是target可能存在范围
- 右区间初始化是 数组的长度值
3. 移除元素
关联 leetcode 27.移除元素
- 做题建议
-
暴力解法
func removeElement(nums []int, val int) int { /*暴力解法*/ size := len(nums) for i := 0; i < size; i++ { if nums[i] == val { // 移动后续所有元素 for j := i + 1; j < size; j++ { nums[j-1] = nums[j] } i-- size-- } } return size }
-
双指针方法【精髓】
func removeElement(nums []int, val int) int { // 使用slow指针存储新数组元素,fast指针来遍历比较对象 slow := 0 // 存新数组元素 for fast := 0; fast < len(nums); fast++ { if nums[fast] != val { nums[slow] = nums[fast] slow++ } } return slow }
-
指针方法【leetcode-最优解】
// 也是双指针,不过是头尾,保证单向遍历,同时也在缩小范围 func removeElement(nums []int, val int) int { j := len(nums)-1 for i:=0;i<=j; { if nums[i] == val { nums[i],nums[j] = nums[j],0 // 把将匹配的元素扔到末尾,结果并不关心 j-- }else{ i++ // 不匹配继续向前走 } } return j+1 }
-