leetcode刷题类型(一)- - - 双指针类型

在排好序的数组或是链表中,两个指针朝着左右方向移动(双指针分为同向双指针和异向双指针),找一些组合满足某种限制条件。

经典题目

167 有序数组的两数和

给定一个已按照 非递减顺序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target

func twoSum(numbers []int, target int) []int {
	i := 0
	j := len(numbers) - 1
	a := make([]int, 2)
	for i < j {
		if numbers[i]+numbers[j] == target {
			a[0] = i + 1
			a[1] = j + 1
			break
		} else {
			if numbers[i]+numbers[j] > target {  //和大于目标值时,说明右值应该减小
				j--
			} else {
				i++
			}
		}
	}
	return a
}
633 平方数之和

给定一个非负整数 c ,你要判断是否存在两个整数 ab,使得 a2 + b2 = c

func judgeSquareSum(c int) bool {
	i := 0
	j := (int)(math.Sqrt(float64(c)))  //0^2+j^2=c,所以j最大是c的平方根,剪枝降低时间复杂度
	for i <= j {
		m := i*i + j*j
		if m == c {
			return true
		} else {
			if m < c {
				i++
			} else {
				j--
			}
		}
	}
	return false
}

345 反转字符串中的元音字母

给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。

func reverseVowels(s string) string {
	//将所有元音字母加入map
	dict := make(map[uint8]int)
	dict['a'] = 1
	dict['e'] = 1
	dict['o'] = 1
	dict['u'] = 1
	dict['i'] = 1
	dict['A'] = 1
	dict['E'] = 1
	dict['O'] = 1
	dict['U'] = 1
	dict['I'] = 1
	//将字符串转为byte数组
	arr := []byte(s)
	length := len(arr)
	i := 0
	j := length - 1
	for true {
		for i < length {
			if _, ok := dict[arr[i]]; ok {  //左指针找到元音字母
				break
			}
			i++
		}
		for j > 0 {
			if _, ok := dict[arr[j]]; ok {  //右指针找到元音字母
				break
			}
			j--
		}
		if i >= j {   //左右指针相遇后交换结束
			break
		}
		//交换左右指针的元音字母
		tmp := arr[i]
		arr[i] = arr[j]
		arr[j] = tmp
		i++
		j--
	}
	return string(arr)
}

还有经典的快速排序~

如有不对,烦请指出~

参考自:
http://www.cyc2018.xyz/
https://leetcode-cn.com/problems