Redian新闻
>
LeetCode 力扣官方题解 | 917. 仅仅反转字母

LeetCode 力扣官方题解 | 917. 仅仅反转字母

公众号新闻

917.仅仅反转字母(点击文末阅读原文查看题目)


题目描述


给你一个字符串 s ,根据下述规则反转字符串:

  • 所有非英文字母保留在原有位置。

  • 所有英文字母(小写或大写)位置反转。

返回反转后的 s。



示例 1:

输入:s = "ab-cd"输出:"dc-ba"


示例 2:

输入:s = "a-bC-dEf-ghIj"输出:"j-Ih-gfE-dCba"


示例 3:

输入:s = "Test1ng-Leet=code-Q!"输出:"Qedo1ct-eeLg=ntse-T!"

 

提示:

  • 1 <= s.length <= 100

  • s 仅由 ASCII 值在范围 [33, 122] 的字符组成

  • s 不含 '\"' 或 '\\'


解决方案

方法一:双指针


思路

我们使用 left 指针从左边开始扫描字符串 s,right 指针从右边开始扫描字符串 s。如果两个指针都扫描到字母,且 left < right,那么交换 s[left] 和 s[right],然后继续进行扫描;否则表明反转过程结束,返回处理后的字符串。

代码

Python3

class Solution:    def reverseOnlyLetters(self, s: str) -> str:        ans = list(s)        left, right = 0, len(ans) - 1        while True:            while left < right and not ans[left].isalpha():  # 判断左边是否扫描到字母                left += 1            while right > left and not ans[right].isalpha():  # 判断右边是否扫描到字母                right -= 1            if left >= right:                break            ans[left], ans[right] = ans[right], ans[left]            left += 1            right -= 1        return ''.join(ans)


C++

class Solution {public:    string reverseOnlyLetters(string s) {        int n = s.size();        int left = 0, right = n - 1;        while (true) {            while (left < right && !isalpha(s[left])) { // 判断左边是否扫描到字母                left++;            }            while (right > left && !isalpha(s[right])) { // 判断右边是否扫描到字母                right--;            }            if (left >= right) {                break;            }            swap(s[left], s[right]);            left++;            right--;        }        return s;    }};


Java

class Solution {    public String reverseOnlyLetters(String s) {        int n = s.length();        char[] arr = s.toCharArray();        int left = 0, right = n - 1;        while (true) {            while (left < right && !Character.isLetter(s.charAt(left))) { // 判断左边是否扫描到字母                left++;            }            while (right > left && !Character.isLetter(s.charAt(right))) { // 判断右边是否扫描到字母                right--;            }            if (left >= right) {                break;            }            swap(arr, left, right);            left++;            right--;        }        return new String(arr);    }
public void swap(char[] arr, int left, int right) { char temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; }}


C#

public class Solution {    public string ReverseOnlyLetters(string s) {        int n = s.Length;        char[] arr = s.ToCharArray();        int left = 0, right = n - 1;        while (true) {            while (left < right && !char.IsLetter(s[left])) { // 判断左边是否扫描到字母                left++;            }            while (right > left && !char.IsLetter(s[right])) { // 判断右边是否扫描到字母                right--;            }            if (left >= right) {                break;            }            Swap(arr, left, right);            left++;            right--;        }        return new String(arr);    }
public void Swap(char[] arr, int left, int right) { char temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; }}


C

static inline void swap(char *c1, char *c2) {    char tmp = *c1;    *c1 = *c2;    *c2 = tmp;}
char *reverseOnlyLetters(char *s){ int n = strlen(s); int left = 0, right = n - 1; while (true) { while (left < right && !isalpha(s[left])) { // 判断左边是否扫描到字母 left++; } while (right > left && !isalpha(s[right])) { // 判断右边是否扫描到字母 right--; } if (left >= right) { break; } swap(s + left, s + right); left++; right--; } return s;}


Golang

func reverseOnlyLetters(s string) string {    ans := []byte(s)    left, right := 0, len(s)-1    for {        for left < right && !unicode.IsLetter(rune(s[left])) { // 判断左边是否扫描到字母            left++        }        for right > left && !unicode.IsLetter(rune(s[right])) { // 判断右边是否扫描到字母            right--        }        if left >= right {            break        }        ans[left], ans[right] = ans[right], ans[left]        left++        right--    }    return string(ans)}


JavaScript

var reverseOnlyLetters = function(s) {    const n = s.length;    const arr = [...s];    let left = 0, right = n - 1;    while (true) {        while (left < right && !(/^[a-zA-Z]+$/.test(s[left]))) { // 判断左边是否扫描到字母            left++;        }        while (right > left && !(/^[a-zA-Z]+$/.test(s[right]))) { // 判断右边是否扫描到字母            right--;        }        if (left >= right) {            break;        }        swap(arr, left, right);        left++;        right--;    }    return arr.join('');};
const swap = (arr, left, right) => { const temp = arr[left]; arr[left] = arr[right]; arr[right] = temp;}


复杂度分析

  • 时间复杂度:O(n),其中 n 是字符串 s 的长度。反转过程需要 O(n),C 语言计算字符串长度需要 O(n)。

  • 空间复杂度:O(1) 或 O(n)。某些语言字符串不可变,需要 O(n) 的额外空间。


BY / 

本文作者:力扣

编辑&版式:Irene

声明:本文归“力扣”版权所有,如需转载请联系。


点个在看,少个 bug

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
发现了《Leetcode刷题指南》,我半年成功转码上岸Careers Stalled, China’s Liberal Arts Grads Learn to CodeXcode弃用Bitcode,导致应用体积大幅增加力扣特别策划 | 挑战不可能的运算商科留学生转码必备:Leetcode到底该怎么刷?题都白刷了?Amazon导师亲自为你揭秘LeetCode刷题真相!谷歌亚麻,越来越嫌弃Leetcode刷题家…跨性别选手暴力扣杀,女排球员用脸接球导致脑震荡两周...LeetCode 力扣官方题解 | 969. 煎饼排序九月九日引起的众生相气候变化 | IEEE 2023主席Saifur Rahman和IEEE代表团出席COP27LeetCode 力扣官方题解 | 537. 复数乘法LeetCode刷完200道题,我竟然收到了亚麻的拒信...Leetcode出题人,揭秘打工体验!LeetCode 力扣官方题解 | 1791. 找出星型图的中心节点刷力扣题想要做到 Bug Free 需培养怎样的思维?投稿延期 | IEEE ICC 2023(IEEE国际通信会议)LeetCode 力扣官方题解 | 6. Z 字形变换另一种“推翻” VS Code 的尝试:JetBrains Fleet 现开放公测LeetCode 力扣官方题解 | 838. 推多米诺澳洲191签证开放申请,491/491转PR要求详解!GitHub疯传!求职亚麻的留学生,请立即停止刷LeetCode!挑战刷最少的题进大厂!不会刷leetcode的人,救星来了程序员必须要掌握的算法技术要点|附赠力扣大厂面试题力扣刷题技巧篇|程序员萌新如何高效刷题LeetCode 力扣官方题解 | 2016. 增量元素之间的最大差值小农思维与集中力量办大事2022傅雷翻译出版奖获奖者揭晓 Le palmarès du Prix Fu Lei 2022 dévoiléIEEE is Your Professional Home - 会员精选视频为你诠释“IEEE如何引领你的专业发展”35岁被裁,刷LeetCode变成了自我感动...家徒四壁精心打造、跌宕起伏的骗局LeetCode 力扣官方题解 | 2104. 子数组范围和OPERALeetCode 力扣官方题解 | 258. 各位相加
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。