go语言实现前缀和

前缀和是实现数组区间和的一种方法,其原理在于预先将一个数组的起始位置到数组任意位置的数值和存入另一个新的数组中,这个新的数组就叫前缀和数组。通过这种方法可以快速查询数组一段区间的和,适用于需要频繁查询数组某段区间和的场景。其主要思想是以空间换时间。需要注意的是该前缀指的是数组的下标,且求数组前缀和分为一维和二维的。代码如下:

一维:

func PrefixSumOne(arr []int, start, end int) int {
	if start < 0 {
		return -1
	}
	arrSum := make([]int, len(arr))
	for i, v := range arr {
		if i == 0 {
			continue
		}
		arrSum[i] = arrSum[i-1] + v
	}
	return arrSum[end] - arrSum[start] + arr[start]
}

其步骤为:1.判定边界条件2.创建一个和原数组一样大的前缀数组。

3.通过“当前前缀和等于前一个前缀和加上原数组当前前缀的数值”依次填满前缀数组。

4.求原数组某个区间数值和“arrSum[end] - arrSum[start-1] ”但是上面代码考虑到当起始为0时,start-1越界,所以采用“arrSum[end] - arrSum[start] + arr[start]”(同时也减少了一次赋值)

而二维数组的思想与一维相同,代码如下:

func PrefixSumTwo(arr [][]int, rowStart, rowEnd, columnStart, columnEnd int) int {
	rowStart = rowStart - 1
	columnStart = columnStart - 1
	if rowStart < -1 || columnStart < -1 || columnStart > columnEnd || rowStart > rowEnd || columnEnd > len(arr[0])-1 || rowEnd > len(arr)-1 {
		return -1
	}
	arrSum := make([][]int, len(arr))
	for i := range arr {
		arrSum[i] = make([]int, len(arr[i]))
	}
	//第一行的前缀和
	for j := 0; j < len(arr[0]); j++ {
		if j == 0 {
			arrSum[0][j] = arr[0][j]
		} else {
			arrSum[0][j] = arrSum[0][j-1] + arr[0][j]
		}
	}
	//第一列的前缀和
	for i := 1; i < len(arr); i++ {
		arrSum[i][0] = arrSum[i-1][0] + arr[i][0]
	}
	for i := 1; i < len(arr); i++ {
		for j := 1; j < len(arr[i]); j++ {
			arrSum[i][j] = arrSum[i-1][j] + arrSum[i][j-1] - arrSum[i-1][j-1] + arr[i][j]
		}
	}
	fmt.Println(arrSum)
	prefixSum := arrSum[rowEnd][columnEnd]
	if rowStart == -1 && columnStart != -1 {
		prefixSum = prefixSum - arrSum[rowEnd][columnStart]
	}
	if columnStart == -1 && rowStart != -1 {
		prefixSum -= arrSum[rowStart][columnEnd]
	}
	if columnStart != -1 && rowStart != -1 {
		prefixSum = prefixSum - arrSum[rowStart][columnEnd] - arrSum[rowEnd][columnStart] + arrSum[rowStart][columnStart]
	}
	return prefixSum
}

只是二维数组的边界判定条件更为复杂,并且步骤三有所不同,其核心代码为

arrSum[i][j] = arrSum[i-1][j] + arrSum[i][j-1] - arrSum[i-1][j-1] + arr[i][j]

下面用形象的图像表示:

求红色区域      其面积=整个面积-两个长方形面积+重叠的正方形面积

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Go 语言中,可以使用 strings 包提供的函数来解析字符串。以下是一些常用的函数: 1. strings.Split(s, sep):将字符串 s 按照分隔符 sep 进行分割,返回一个字符串数组。 2. strings.Trim(s, cutset):将字符串 s 去掉 cutset 中指定的字符。 3. strings.Replace(s, old, new, n):将字符串 s 中的 old 替换为 new,n 指定替换的次数,-1 表示全部替换。 4. strings.HasPrefix(s, prefix):判断字符串 s 是否以 prefix 开头。 5. strings.HasSuffix(s, suffix):判断字符串 s 是否以 suffix 结尾。 6. strings.Index(s, substr):查找字符串 s 中 substr 的位置,返回第一个匹配的位置,如果没有匹配则返回 -1。 7. strings.LastIndex(s, substr):查找字符串 s 中 substr 的位置,返回最后一个匹配的位置,如果没有匹配则返回 -1。 示例代码: ```go package main import ( "fmt" "strings" ) func main() { // 分割字符串 str := "hello,world" arr := strings.Split(str, ",") fmt.Println(arr) // [hello world] // 去掉指定字符 str2 := "hello,world\n" str2 = strings.Trim(str2, "\n") fmt.Println(str2) // hello,world // 替换字符串 str3 := "hello,world" str3 = strings.Replace(str3, "world", "golang", -1) fmt.Println(str3) // hello,golang // 判断字符串是否以指定前缀开头 str4 := "hello,world" if strings.HasPrefix(str4, "hello") { fmt.Println("str4 starts with hello") } // 判断字符串是否以指定后缀结尾 str5 := "hello,world" if strings.HasSuffix(str5, "world") { fmt.Println("str5 ends with world") } // 查找字符串中指定子串的位置 str6 := "hello,world" index := strings.Index(str6, "world") fmt.Println(index) // 6 } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值