[Go版]算法通关村第十二关白银——字符串经典基础面试题

反转专题

题目:反转字符串

题目链接:LeetCode-344. 反转字符串
在这里插入图片描述

思路分析:左右双指针 + 对向交换

复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( 1 ) O(1) O(1)

Go代码

func reverseString(s []byte)  {
    
    
    length := len(s)
    left, right := 0, length-1
    for left <= right {
    
    
        s[left], s[right] = s[right], s[left]
        left++
        right--
    }
    return
}

题目:反转字符串 II

题目链接:LeetCode-541. 反转字符串 II
在这里插入图片描述

思路分析:K个一组反转思想(找到每组的首尾索引)

复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)

Go代码

func reverseStr(s string, k int) string {
    
    
    arr := []byte(s)
    length := len(arr)
    left := 0
    for left < length {
    
    
        // 剩余字符少于 k 个,则将剩余字符全部反转。
        if (length-left) < k {
    
    
            reverse(arr, left, length-1)
        } else {
    
    
            reverse(arr, left, left+k-1)
        }
        left = left+k*2
    }
    return string(arr)
}

func reverse(s []byte, left int, right int) {
    
    
    if left >= right {
    
    
        return
    }
    for left<=right {
    
    
        s[left], s[right] = s[right], s[left]
        left++
        right--
    }
}

题目:仅仅反转字母

题目链接:LeetCode-917. 仅仅反转字母
在这里插入图片描述

思路分析:左右双指针 + 对向交换字母 + 跳过非字母

复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)

Go代码

func reverseOnlyLetters(s string) string {
    
    
    arr := []byte(s)
    length := len(arr)
    left, right := 0, length-1
    for left <= right {
    
    
        for left <= right && notA2z(arr[left]) {
    
    
            left++
        }
        for left <= right && notA2z(arr[right]) {
    
    
            right--
        }
        if left <= right {
    
    
            arr[left], arr[right] = arr[right], arr[left]
            left++
            right--
        }
    }
    return string(arr)
}

func notA2z (ch byte) bool {
    
    
    // 大写字母 A - Z 的 ASCII 码范围为 [65,90]
    // 小写字母 a - z 的 ASCII 码范围为 [97,122]
    if ch < 65 || ch > 122 {
    
    
        return true
    }
    if ch > 90 && ch < 97 {
    
    
        return true
    }
    return false
}

题目:反转字符串中的单词

题目链接:LeetCode-151. 反转字符串中的单词
在这里插入图片描述

思路分析:去除空格 + 全面反转 + K个一组反转思想(K不定长,找到每组首尾索引)

  1. 去除字符串两端的空格
  2. 对整个去除空格后的字符串进行了一次反转
  3. 遍历字符串中的每个单词,将它们进行反转,并拼接成一个新的字符串
    在这里插入图片描述
    与这个图的思路大致相同,不过我们实现是在 翻转每个单词后 加上 一个空格 存储数组中返回。

复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)

Go代码

func reverseWords(s string) string {
    
    
    arr := []byte(s)
    length := len(arr)
    left, right := 0, length-1
    // 去除首尾空格
    for {
    
    
        if arr[left] == ' ' {
    
    
            left++
        } else {
    
    
            break
        }
    }
    for {
    
    
        if arr[right] == ' ' {
    
    
            right--
        } else {
    
    
            break
        }
    }
    var arr2 []byte
    if right < length-1 {
    
    
        arr2 = arr[left:right+1]
    } else {
    
    
        arr2 = arr[left:]
    }
    length = len(arr2)
    reverse(arr2, 0, length-1)
    var arr3 []byte
    left = 0
    for left < length {
    
    
        for left < length {
    
    
            if arr2[left] == ' ' {
    
    
                left++
            } else {
    
    
                break
            }
        }
        right = left
        for right < length {
    
    
            if arr2[right] == ' ' {
    
    
                break
            } else {
    
    
                right++
            }
        }
        reverse(arr2, left, right-1)
        arr3 = append(arr3, arr2[left:right]...)
        if right == length {
    
    
            break
        }
        arr3 = append(arr3, ' ')
        left = right
    }
    return string(arr3)
}

func reverse(arr []byte, left int, right int) {
    
    
    if left >= right {
    
    
        return 
    }
    for left <= right {
    
    
        arr[left], arr[right] = arr[right], arr[left]
        left++
        right--
    }
}

题目:验证回文串

题目链接:LeetCode-125. 验证回文串
在这里插入图片描述

思路分析:只留下有效字符后,左右双指针对向比较值

复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)

Go代码

func isPalindrome(s string) bool {
    
    
    arr := []rune{
    
    }
    for _, v := range s {
    
    
        if res, ch := isValid(v); res {
    
    
            arr = append(arr, ch)
        }
    }
    length := len(arr)
    left, right := 0, length-1
    for left<=right {
    
    
        if arr[left] != arr[right] {
    
    
            return false
        }
        left++
        right--
    }
    return true
}

func isValid(ch rune) (bool, rune) {
    
    
    if ch >= 'A' && ch <= 'Z' {
    
    
        ch = ch | 32
        return true, ch
    }
    if ch >= 'a' && ch <= 'z' {
    
    
        return true, ch
    }
    if ch >= '0' && ch <= '9' {
    
    
        return true, ch
    }
    return false, ch
}

题目:字符串中的第一个唯一字符

题目链接:LeetCode-387. 字符串中的第一个唯一字符
在这里插入图片描述

思路分析:使用哈希表存储字符及其出现次数,遍历找到目标字符

复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( n ) O(n) O(n)

Go代码

func firstUniqChar(s string) int {
    
    
    maps := make(map[rune]int, 0)
    for _, v := range s {
    
    
        maps[v]++
    }
    for i, v := range s {
    
    
        if maps[v] == 1 {
    
    
            return i
        }
    }
    return -1
}

题目:有效的字母异位词(判断是否互为字符重排)

题目链接:LeetCode-242. 有效的字母异位词
在这里插入图片描述

思路分析:使用哈希表存储字符及其出现次数,遍历另一个字符串对哈希表减值,判断是否<0

复杂度:时间复杂度 O ( n ) O(n) O(n)、空间复杂度 O ( k ) O(k) O(k)

  • 空间复杂度为 O ( k ) O(k) O(k),其中 k 是字符串中不同字符的数量,即存储在 map 中的键的数量。

Go代码

func isAnagram(s string, t string) bool {
    
    
    if len(s) != len(t) {
    
    
        return false
    }
    maps := getMap(s)
    for _, v := range t {
    
    
        maps[v]--
        if maps[v] < 0 {
    
    
            return false
        }
    }
    return true
}

func getMap(s string) map[rune]int {
    
    
    ret := make(map[rune]int, 0)
    for _, v := range s {
    
    
        ret[v]++
    }
    return ret
}

猜你喜欢

转载自blog.csdn.net/trinityleo5/article/details/132345093