LeetCode算法 | Day8 字符串:反转字符串、反转字符串II、路径加密、翻转字符串里的单词、动态口令

344. 反转字符串

题目:

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]          

解题思路:

这道题就是用双指针两边互相做交换就行了。

var reverseString = function (s) {
    let left = 0;
    let right = s.length - 1;
    while (left < Math.floor(s.length / 2)) {
        [s[left], s[right]] = [s[right], s[left]]
        left++;
        right--;
    }
    return s;
};

541. 反转字符串II

题目:

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
    示例:
输入:s = "abcdefg", k = 2
输出:"bacdfeg"

解题思路:

这道题需要每次以2k为一段的处理。

  • 每隔 2k 个字符的前 k 个字符进行反转。
  • 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符。
  • 剩余字符少于 k 个,则将剩余字符全部反转。
const reverse = (arr, start, end) => {
    for (let i = start, j = end; i < j; i++, j--) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }
}
var reverseStr = function (s, k) {
    let arr = s.split("");
    for (let i = 0; i < arr.length; i += 2 * k) {
        if (i + k <= s.length) {
            reverse(arr, i, i + k - 1)
            continue;
        }
        reverse(arr, i, s.length - 1);
    }
    return arr.join("");
};

LCR 122. 路径加密

题目:

假定一段路径记作字符串 path,其中以 "." 作为分隔符。现需将路径加密,加密方法为将 path 中的分隔符替换为空格 " ",请返回加密后的字符串。
示例:

输入:path = "a.aef.qerf.bb"
输出:"a aef qerf bb"

解题思路:

这道题原题目来自于剑指offer 05. 替换空格,JavaScript语法直接用数组api替换即可。

var pathEncryption = function (path) {
    return path.split(".").join(" ");
};

参考题目:

替换数字

const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
const isNumber = (num) => {
    return !isNaN(parseFloat(num));
}
const processInput = () => {
    rl.on("line", (input) => {
        let count = 0;
        for (let i = 0; i < input.length; i++) {
            if (isNumber(input[i])) {
                count++;
            }
        }
        const arr = new Array(input.length + count * 5).fill(0);
        for (let i = arr.length - 1, j = input.length - 1; i >= 0; i--, j--) {
            if (!isNumber(input[j])) {
                arr[i] = input[j];
            } else {
                arr[i] = "r";
                arr[i - 1] = "e";
                arr[i - 2] = "b";
                arr[i - 3] = "m";
                arr[i - 4] = "u";
                arr[i - 5] = "n";
                i -= 5;
            }
        }
        console.log(arr.join(""));
    });
};
processInput();

151.翻转字符串里的单词

题目:

给你一个字符串 s ,请你反转字符串中 单词 的顺序。
单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。
返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。
注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
示例:

输入:s = "the sky is blue"
输出:"blue is sky the"

解题思路:

分为三步来处理:

  1. 删除多余空格:利用快慢指针,快指针寻找有用的字符,慢指针用来计数。在遇到慢指针不为0的情况下说明是单词之间的空格,此时加入空格。最后还需要修改数组长度。
  2. 对整体进行翻转。
  3. 对每个单词进行翻转,注意边界条件处理。
const reverse = (arr, start, end) => {
    for (let i = start, j = end; i < j; i++, j--) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }
}
const removeExtraSpaces = (arr) => {
    let slow = 0;
    for (let fast = 0; fast < arr.length; fast++) {
        if (arr[fast] !== " ") {
            if (slow !== 0) {
                arr[slow] = " ";
                slow++;
            }
            while (fast < arr.length && arr[fast] !== " ") {
                arr[slow++] = arr[fast++];
            }
        }
    }
    arr.length = slow;
}
var reverseWords = function (s) {
    const arr = s.split("");
    removeExtraSpaces(arr);
    reverse(arr, 0, arr.length - 1);
    let start = 0;
    for (let i = 0; i <= arr.length; i++) {
        if (i === arr.length || arr[i] === " ") {
            reverse(arr, start, i - 1);
            start = i + 1
        }
    }
    return arr.join("");
};

LCR 182. 动态口令

题目:

某公司门禁密码使用动态口令技术。初始密码为字符串 password,密码更新均遵循以下步骤:

  • 设定一个正整数目标值 target
  • 将 password 前 target 个字符按原顺序移动至字符串末尾
    请返回更新后的密码字符串。
    示例 :
输入: password = "s3cur1tyC0d3", target = 4
输出: "r1tyC0d3s3cu"

解题思路

这道题原题目来自于剑指offer 58 II. 左旋转字符串。整体思路就是三次字符串反转,就可以达到效果。

const reverse = (arr, start, end) => {
    for (let i = start, j = end; i < j; i++, j--) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }
};
var dynamicPassword = function (password, target) {
    const arr = password.split("");
    reverse(arr, 0, arr.length - 1);
    reverse(arr, 0, arr.length - target - 1);
    reverse(arr, arr.length - target, arr.length - 1);
    return arr.join("");
};

参考题目:

右旋字符串

const readline = require("readline");
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
const iter = rl[Symbol.asyncIterator]();
const read_line = async () => (await iter.next()).value;
const reverse = (arr, start, end) => {
    for (let i = start, j = end; i < j; i++, j--) {
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }
};
const processInput = async () => {
    const n = Number(await read_line());
    const str = await read_line();
    const arr = str.split("");
    reverse(arr, 0, arr.length - 1 - n);
    reverse(arr, arr.length - n, arr.length - 1);
    reverse(arr, 0, arr.length - 1);
    console.log(arr.join(""));
};
processInput();

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容