题目:
给你一个小写英文字母组成的字符串 s 和一个二维整数数组 shifts ,其中 shifts[i] = [starti, endi, directioni] 。对于每个 i ,将 s 中从下标 starti 到下标 endi (两者都包含)所有字符都进行移位运算,如果 directioni = 1 将字符向后移位,如果 directioni = 0 将字符向前移位。
将一个字符 向后 移位的意思是将这个字符用字母表中 下一个 字母替换(字母表视为环绕的,所以 'z' 变成 'a')。类似的,将一个字符 向前 移位的意思是将这个字符用字母表中 前一个 字母替换(字母表是环绕的,所以 'a' 变成 'z' )。
请你返回对 s 进行所有移位操作以后得到的最终字符串。
算法:
方法一:差分数组
前缀和适用于原始数组不变,多次范围查询的场景。
差分数组适合,多次范围变化,最后通过差分还原前缀和,再范围查询的场景。
func shiftingLetters(s string, shifts [][]int) string {
diff := make([]int, len(s) + 1)
// 计算差分数组
for i := range shifts {
val := shifts[i][2]
// 左移一位相当于右移25位
if val == 0 {
val = -1
}
diff[shifts[i][0]] = diff[shifts[i][0]] + val
diff[shifts[i][1] + 1] = diff[shifts[i][1] + 1] - val
}
// 通过差分数组,还原前缀和,计算每一位的移动数
for i := 1; i < len(diff); i ++ {
diff[i] = diff[i - 1] + diff[i]
}
// fmt.Println(diff)
byt := []byte(s)
for i := range byt {
// 可能有负数,加上26再求余,左移一位-1相当于右移25位+25
// (int(byt[i] - 'a' ) + diff[i]) % 26 防溢出
byt[i] = byte('a' + ((int(byt[i] - 'a' ) + diff[i]) % 26 + 26 ) % 26)
}
return string(byt)
}