力扣之僅僅反轉字母(雙指標方式)

水冗水孚發表於2023-02-04

題目描述

給你一個字串 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!"

 

力扣原題目地址:https://leetcode.cn/problems/...

思路分析

透過題目我們可以得出幾個關鍵詞需求:

  • 需要判斷英文字母和非英文字母
  • 英文字母字串位置反轉,即交換位置

判斷英文字母和非英文字母

我們可以透過字串的charCodeAt方法去做區間判斷,或者定義一個變數字串儲存所有的大小寫應為字母

charCodeAt方法

即為 [65,90] | [97,122] 區間內的都是英文字母

變數字串

封裝函式方便判斷

function isLetter(s) {
    let str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    return str.includes(s)
}

也是列舉思想,即判斷某一個值,是否在所有的列舉值中...

英文字母字串位置交換

注意!注意!注意!這裡有一個坑!

我們知道,陣列中的兩項如果要交換位置,直接定義一個臨時變數,去透過索引交換位置即可。如下:

let arr = ['甲', '乙', '丙', '丁']
let temp
temp = arr[0]
arr[0] = arr[3]
arr[3] = temp
console.log(arr); // ['丁', '乙', '丙', '甲']

陣列直接可以交換成功,但是字串直接交換不成功!如下:

let str = 'abcd'
let temp
temp = str[0]
str[0] = str[3]
str[3] = temp
console.log(str); // abcd

是的,列印出來的str並不是dbca,所以如果我們想要交換字串中的字母的位置,需要,將字串轉成陣列交換位置以後,再轉回來。

程式碼

透過上述的分析,結合雙指標交換位置的操作,於是我們得出以下程式碼:

// 判斷是否是大小寫英文字母
function isLetter(s) {
    let str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    return str.includes(s)
}

var reverseOnlyLetters = function (s) {
    s = s.split('') // 字串轉陣列
    let l = 0 // 左側指標
    let r = s.length - 1 // 右側指標
    while (l < r) {
        if (!isLetter(s[l])) { // 左邊不是字母,左邊往右走
            l = l + 1
        }
        if (!isLetter(s[r])) { // 右邊不是字母,右邊往左走
            r = r - 1
        }
        if (isLetter(s[l]) & isLetter(s[r])) { // 如果左右都是字母,才交換值,相向而行
            let temp;
            temp = s[l]
            s[l] = s[r]
            s[r] = temp
            l = l + 1
            r = r - 1
        }
    }
    return s.join('') // 操作完以後,再轉回字串
};

提交結果圖

還行...

相關文章