848. Shifting Letters**

848. Shifting Letters**

https://leetcode.com/problems/shifting-letters/

题目描述

We have a string S of lowercase letters, and an integer array shifts.

Call the shift of a letter, the next letter in the alphabet, (wrapping around so that 'z' becomes 'a').

For example, shift('a') = 'b', shift('t') = 'u', and shift('z') = 'a'.

Now for each shifts[i] = x, we want to shift the first i+1 letters of S, x times.

Return the final string after all such shifts to S are applied.

Example 1:

Input: S = "abc", shifts = [3,5,9]
Output: "rpl"
Explanation: 
We start with "abc".
After shifting the first 1 letters of S by 3, we have "dbc".
After shifting the first 2 letters of S by 5, we have "igc".
After shifting the first 3 letters of S by 9, we have "rpl", the answer.

Note:

  • 1 <= S.length = shifts.length <= 20000
  • 0 <= shifts[i] <= 10 ^ 9

C++ 实现 1

这题本身并不难, 关键在于要防止 overflow. 拿例子来说, 对于 c, 需要移动 9 次, 而对 b 来说, 需要移动 9 + 5 = 14 次, 而 a 需要移动 9 + 5 + 3 = 17 次. 对 26 (26 个小写字母) 求余. 但这是 shifts 中的值较小的情况. 如果 shifts 中的值很大, 从后向前累加, 可能会造成整数 overflow. 这时, 需要提前求余:

class Solution {
private:
    char shift(const char &c, int n) {
        char res = (c - 'a' + n) % 26 + 'a';
        return res;
    }
public:
    string shiftingLetters(string S, vector<int>& shifts) {
    	// 累加和的时候就应该求余
        for (int i = shifts.size() - 2; i >= 0; -- i)
            shifts[i] = (shifts[i + 1] + shifts[i]) % 26;
        for (int i = 0; i < S.size(); ++ i)
            S[i] = shift(S[i], shifts[i]);
        return S;
    }
};

原理在于公式: 可以参看 974. Subarray Sums Divisible by K**

(a + b) mod n = [(a mod n) + (b mod n)] mod n
(a mod n) mod n = a mod n

n - 3 这个位置的公式推导:

在这里插入图片描述

C++ 实现 2

也可以写成如下的形式:

class Solution {
private:
    char shift(const char &c, int n) {
        char res = (c - 'a' + n) % 26 + 'a';
        return res;
    }
public:
    string shiftingLetters(string S, vector<int>& shifts) {
        int prev = 0;
        for (int i = S.size() - 1; i >= 0; -- i) {
            prev = (prev + shifts[i] % 26) % 26;
            // 注意和 C++ 实现 1 不同的是, 这里的第二个参数是 prev
            S[i] = shift(S[i], prev);
        }
        return S;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值