算法设计思想(8)— 双指针之左右指针(二分搜索、两数之和、翻转数组)

左、右指针一般运用在数组或者字符串中,实际是指两个索引值,一般初始化为 left=0,right = len(nums)-1。

1. 二分搜索

func binarySearch(a []int, target int) int {
	left := 0
	right := len(a) - 1
	// 因为搜素区间是 [left, right],左右都是封闭的,所以循环时应该是 <=
	for left <= right {
		mid := left + (right-left)/2
		if a[mid] == target {
			return mid
		} else if a[mid] < target {
			left = mid + 1
		} else if a[mid] > target {
			right = mid - 1
		}
	}
	return -1
}

2. 两数之和

一个已按照升序排列的有序数组 nums 和一个目标值 target ,在 nums 中找到两个数使得它们相加之和等于 target ,请返回这两个数字的索引。比如输入 [2,7,11,15],target = 13 ,返回结果 [0,2]。

func findIndex(a []int, target int) []int {
	left := 0
	right := len(a) - 1
	indexSlice := make([]int, 0)
	for left <= right {
		sum := a[left] + a[right]
		if sum > target {
			right-- // 让 sum 结果变小些
		} else if sum < target {
			left++ // 让 sum 结果变大些
		} else if sum == target {
			indexSlice = append(indexSlice, left, right)
			return indexSlice
		}
	}
	return nil
}

func main() {
	arr := []int{2, 3, 4, 5, 6, 9, 11, 15}
	fmt.Println(findIndex(arr, 31))
}

3. 翻转数组

func reverse(a []int) []int {
	left := 0
	right := len(a) - 1
	for left <= right {
		temp := a[left]
		a[left] = a[right]
		a[right] = temp
		left++
		right--
	}
	return a
}

func main() {
	arr := []int{2, 3, 4, 5, 6, 9, 11, 15}
	fmt.Println(reverse(arr))
}

4. 调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。

func exchange(nums []int) []int {
    left := 0
    right := len(nums) - 1
    for left <= right {
    	// 左指针找偶数
        if nums[left] & 1 == 1 {
            left++
        // 右指针找奇数
        }else if nums[right] & 1 == 0 {
            right--
        // 如果左指针为偶数,右指针为奇数,那么交换位置
        }else if nums[left] & 1 == 0 && nums[right] & 1 == 1 {
            temp := nums[left]
            nums[left] = nums[right]
            nums[right] = temp
            left++
            right--
        }
    }
    return nums
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设有一个 $n \times n$ 的二维数组 $matrix$,我们要将其顺时针旋转 $90$ 度,可以通过以下步骤实现: 1. 先将矩阵沿主对角线翻转,即将 $matrix[i][j]$ 与 $matrix[j][i]$ 交换。 2. 再将每一行沿中心线翻转,即将 $matrix[i][j]$ 与 $matrix[i][n-1-j]$ 交换。 代码如下: ```c++ void rotate(int** matrix, int matrixSize, int* matrixColSize){ // Step 1: 沿主对角线翻转 for(int i=0; i<matrixSize; i++){ for(int j=i; j<matrixSize; j++){ int temp = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = temp; } } // Step 2: 每一行沿中心线翻转 for(int i=0; i<matrixSize; i++){ for(int j=0; j<matrixSize/2; j++){ int temp = matrix[i][j]; matrix[i][j] = matrix[i][matrixSize-1-j]; matrix[i][matrixSize-1-j] = temp; } } } ``` 在使用指针旋转的时候,我们需要将二维数组转化为一维指针,这里我们可以使用 $int* matrix$ 来表示二维数组,其中 $matrix[i][j]$ 可以表示为 $matrix[i \times n + j]$,其中 $n$ 表示矩阵的宽度或长度。 代码如下: ```c++ void rotate(int* matrix, int matrixSize, int* matrixColSize){ // Step 1: 沿主对角线翻转 for(int i=0; i<matrixSize; i++){ for(int j=i; j<matrixSize; j++){ int temp = *(matrix + i * matrixSize + j); *(matrix + i * matrixSize + j) = *(matrix + j * matrixSize + i); *(matrix + j * matrixSize + i) = temp; } } // Step 2: 每一行沿中心线翻转 for(int i=0; i<matrixSize; i++){ for(int j=0; j<matrixSize/2; j++){ int temp = *(matrix + i * matrixSize + j); *(matrix + i * matrixSize + j) = *(matrix + i * matrixSize + matrixSize - 1 - j); *(matrix + i * matrixSize + matrixSize - 1 - j) = temp; } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值