算法训练Day 8

LeetCode 344. 反转字符串

题目链接:344. 反转字符串

思路:双指针法,比较简单的一道题。

Python版本:

class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        l, r = 0, len(s)-1
        while l<=r:
            s[l],s[r] = s[r],s[l]
            l += 1
            r -= 1

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

go版本:

func reverseString(s []byte)  {
    l, r := 0, len(s)-1
    for l<=r {
        s[l], s[r] = s[r], s[l]
        l++
        r--
    }
}

LeetCode 541. 反转字符串 II

题目链接:541. 反转字符串 II

思路:和上一题思路类似,只是多了一个细节,就是每次需要判断一下 i + k i+k i+k是否越界,i每次移动的步长是2k。

Python代码:

class Solution:
    def reverseStr(self, s: str, k: int) -> str:
        def reverseS(s):
            l, r = 0, len(s)-1
            while l<r:
                s[l],s[r] = s[r],s[l]
                l += 1
                r -= 1
            return s
        
        ss = list(s)
        i = 0
        while i < len(ss):
            if i+k <= len(ss):
                ss[i:i+k] = reverseS(ss[i:i+k])
            else:
                ss[i:] = reverseS(ss[i:])
            i += 2*k

        return ''.join(ss)

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

go版本:

func reverseStr(s string, k int) string {
    ss := []byte(s)
    n := len(s)
    for i := 0; i < n; i += 2 * k {
        if i + k <= n {
            reverse(ss[i:i+k])
        } else {
            reverse(ss[i:])
        }
    }
    return string(ss)
}


func reverse(b []byte) {
    l := 0
    r := len(b) - 1
    for l < r {
        b[l], b[r] = b[r], b[l]
        l++
        r--
    }
}

LeetCode 剑指 Offer 05. 替换空格

题目链接:剑指 Offer 05. 替换空格

思路:正常的字符串操作,这里使用了一个列表来存放结果。

Python版本:

class Solution:
    def replaceSpace(self, s: str) -> str:
        ss = list(s)
        res = []
        for i in range(len(s)):
            if s[i]==' ':
                res.append("%20")
            else:
                res.append(s[i])
        return ''.join(res)

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

go版本:

func replaceSpace(s string) string {
    ss := []byte(s)
    res := make([]byte, 0)
    for i:=0; i<len(s); i++ {
        if ss[i]==' ' {
            res = append(res, []byte("%20")...)
        } else {
            res = append(res, ss[i])
        }
    }
    return string(res)
}

LeetCode 151. 反转字符串中的单词

题目链接:151. 反转字符串中的单词

思路:观察题目描述和示例,发现需要反转的是单词在句子中的位置,单词自身的字母是不需要反转的,从而通过空格符来作为单词的分隔判断。可以使用Python双端队列支持从队列头部插入的方法,直接按顺序处理单词,然后将单词压入队列的首部。

Python版本:

class Solution:
    def reverseWords(self, s: str) -> str:
        def foo(ss):
            p = 0
            while p < len(ss) and ss[p] == " ":
                p += 1
            return ss[p:]

        s = foo(s)
        s = foo(s[::-1])[::-1]
            
        res, word = collections.deque(), []
        left, right = 0, len(s) - 1
        while left <= right:
            if s[left] == ' ' and word:
                res.appendleft(''.join(word))
                word = []
            elif s[left] != ' ':
                word.append(s[left])
            left += 1
        res.appendleft(''.join(word))
        
        return ' '.join(res)

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

go版本:

func reverseWords(s string) string {
	//1.使用双指针删除冗余的空格
	slowIndex, fastIndex := 0, 0
	b := []byte(s)
	//删除头部冗余空格
	for len(b) > 0 && fastIndex < len(b) && b[fastIndex] == ' ' {
		fastIndex++
	}
    //删除单词间冗余空格
	for ; fastIndex < len(b); fastIndex++ {
		if fastIndex-1 > 0 && b[fastIndex-1] == b[fastIndex] && b[fastIndex] == ' ' {
			continue
		}
		b[slowIndex] = b[fastIndex]
		slowIndex++
	}
	//删除尾部冗余空格
	if slowIndex-1 > 0 && b[slowIndex-1] == ' ' {
		b = b[:slowIndex-1]
	} else {
		b = b[:slowIndex]
	}
	//2.反转整个字符串
	reverse(&b, 0, len(b)-1)
	//3.反转单个单词  i单词开始位置,j单词结束位置
	i := 0
	for i < len(b) {
		j := i
		for ; j < len(b) && b[j] != ' '; j++ {
		}
		reverse(&b, i, j-1)
		i = j
		i++
	}
	return string(b)
}


func reverse(b *[]byte, left, right int) {
	for left < right {
		(*b)[left], (*b)[right] = (*b)[right], (*b)[left]
		left++
		right--
	}
}

顺着代码随想录的思路,看了几遍代码,自己捋着思路实现了一下。

LeetCode 剑指 Offer 58 - II. 左旋转字符串

题目链接:剑指 Offer 58 - II. 左旋转字符串

思路:较简单,使用了一个辅助数组。如果 不使用辅助数组的话,可以借鉴本篇博客第一题和第二题的思路:先翻转n位之前的字母,再翻转n位到最后一位的字母,然后再翻转一遍字符串。

Python版本:

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        res = []
        for i in range(n, len(s)):
            res.append(s[i])
        for i in range(n):
            res.append(s[i])
        return ''.join(res)

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

go版本:

func reverseLeftWords(s string, n int) string {
    res := make([]byte, 0)
    for i:=n; i<len(s); i++ {
        res = append(res, s[i])
    }
    for i:=0; i<n; i++ {
        res = append(res, s[i])
    }
    return string(res)
}

go版本(不使用辅助数组):

func reverseLeftWords(s string, n int) string {
    ss := []byte(s)
    reverseS(ss[n:])
    reverseS(ss[0:n])
    reverseS(ss)
    return string(ss)
}


func reverseS(s []byte)  {
    l, r := 0, len(s)-1
    for l<=r {
        s[l], s[r] = s[r], s[l]
        l++
        r--
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值