字符串

有效的字母异位词

  1. 判断 s, t 的字符计数是否相同
function isAnagram(s: string, t: string): boolean {
    let map = new Map()
    for (let v of s) {
        if (map.has(v)) map.set(v, map.get(v) + 1)
        else map.set(v, 1)
    }
    for (let v of t) {
        if (map.has(v)) map.set(v, map.get(v) - 1)
        else return false
    }
    return [...map.values()].every(x => x === 0)
};

最长回文串

  1. n * xx
  2. n * xx + y
function longestPalindrome(s: string): number {
    let map = new Map()
    for (let v of s) {
        if (map.has(v)) map.set(v, map.get(v) + 1)
        else map.set(v, 1)
    }
 
    let [pairs, single] = [0, 0]
    for (let v of map.values()) {
        pairs += v - v % 2
        single += v % 2
    }
 
    return single ? pairs + 1 : pairs
};

字符串相加

function addStrings(num1: string, num2: string): string {
    let [m, n] = [num1.length, num2.length]
    let maxlen = m > n ? m : n
    let carry = 0
    let res = []
    for (let i = 1; i <= maxlen; i++) {
        let l = Number(num1.at(-i)) || 0
        let r = Number(num2.at(-i)) || 0
        let sum = l + r + carry
        carry = sum >= 10 ? 1 : 0
        res.unshift(sum % 10)
    }
    if (carry) res.unshift(1)
    return res.join('')
};

字符串相乘

function multiply(num1: string, num2: string): string {
    // 相乘 ('123' * '2')
    function times(x: string, y: string): string {
        if (x === '0' || y === '0') return '0'
        let n = x.length
        let res = ''
        let carry = 0
        for (let i = 1; i <= n; i++) {
            let l = Number(x.at(-i)) || 0
            let r = Number(y)
            let sum = l * r + carry
            carry = Math.floor(sum / 10)
            res = sum % 10 + res
        }
        if (carry) res = carry + res
        return res
    }
 
    // 相加 ('123' + '123')
    function add(x: string, y: string): string {
        let n = Math.max(x.length, y.length)
        let res = ''
        let carry = 0
        for (let i = 1; i <= n; i++) {
            let l = Number(x.at(-i)) || 0
            let r = Number(y.at(-i)) || 0
            let sum = l + r + carry
            carry = sum >= 10 ? 1 : 0
            res = sum % 10 + res
        }
        if (carry) res = carry + res
        return res
    }
 
    let pds = [...num1].map((v, i) => {
        let val = times(num2, v)
        if (val === '0') {
            return '0'
        } else {
            return val + '0'.repeat(num1.length - i - 1)
        }
    })
    let sum = pds.reduce((a, b) => add(a, b))
    return sum
};

最长公共前缀

function longestCommonPrefix(strs: string[]): string {
    let i = 0
    for (let v of strs[0]) {
        for (let s of strs) {
            if (v !== s[i]) return strs[0].slice(0, i)
        }
        i++
    }
    return strs[0].slice(0, i)
};

罗马数字转整数

function romanToInt(s: string): number {
    let map = new Map([
        ['I',    1],
        ['V',    5],
        ['X',   10],
        ['L',   50],
        ['C',  100],
        ['D',  500],
        ['M', 1000],
    ])
 
    let sum = 0
    for (let i = 0; i < s.length - 1; i++) {
        let [curr, next] = [map.get(s[i]), map.get(s[i + 1])]
        sum += curr < next ? -curr : curr
    }
    sum += map.get(s.at(-1))
    return sum
};

整数转罗马数字

function intToRoman(num: number): string {
    let map = new Map([
        ['M',  1000],
        ['CM',  900],
        ['D',   500],
        ['CD',  400],
        ['C',   100],
        ['XC',   90],
        ['L',    50],
        ['XL',   40],
        ['X',    10],
        ['IX',    9],
        ['V',     5],
        ['IV',    4],
        ['I',     1]
    ])
    let res = ''
    for (let [k, v] of map) {
        while (num >= v) {
            num -= v
            res += k
        }
    }
    return res
};

第一个匹配项的下标

function strStr(haystack: string, needle: string): number {
    let [m, n] = [haystack.length, needle.length]
    for (let i = 0; i <= m - n; i++) {
        if (haystack.slice(i, i + n) === needle) return i
    }
    return -1
};

最长回文子串

  1. 遍历字符串,每个字符向两边扩散
function longestPalindrome(s: string): string {
    let n = s.length
    let res = ''
 
    // aba
    for (let i = 0; i < n; i++) {
        let [a, b] = [i, i]
        while (a > 0 && b < n - 1 && s[a - 1] === s[b + 1]) {
            a--
            b++
        }
        if (b - a + 1 > res.length) res = s.slice(a, b + 1)
    }
 
    // abba
    for (let i = 0; i < s.length; i++) {
        let [a, b] = [i, i + 1]
        if (s[a] !== s[b]) continue
        while (a > 0 && b < n - 1 && s[a - 1] === s[b + 1]) {
            a--
            b++
        }
        if (b - a + 1 > res.length) res = s.slice(a, b + 1)
    }
 
    return res
};