剑指Offer and Leetcode刷题总结之四:字符串

目录

剑指50:第一个只出现一次的字符||Hashmap

剑指67:把字符串转换成整数||Leetcode8:字符串转换整数 (atoi)(题解参考)

面试题58-I:翻转单词顺序||双指针

面试题58-II:左旋转字符串

Leetcode02:两数相加(链表)

Leetcode415: 字符串相加(大数相加)

Leetcode45:大数相乘

Leetcode344:反转字符串||首尾双指针

其他:字符串数字转换为INT(不能用int函数)


剑指50:第一个只出现一次的字符||Hashmap

基本思路:遍历一遍构造hashmap,对出现多次的value做处理(eg. + size);再遍历一遍找 < size and index最小的;

class Solution50(object):
    def firstUniqChar(self, s):
        if not s: return ' '
        size = len(s)
        dict = {}
        for ind, val in enumerate(s):
            if dict.get(val) == None:
                dict[val] = ind
            else:
                dict[val] +=  size
        mi = size
        for val in dict:
            if dict[val] <= size - 1 and dict[val] < mi: 
                mi = dict[val]
        return s[mi] if mi < size else ' '

剑指67:把字符串转换成整数||Leetcode8:字符串转换整数 (atoi)题解参考

面试题58-I:翻转单词顺序||双指针

题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. ",则输出"student. a am I"。

基本思路:倒序输出即可,遇到空格跳过,双指针截取单词首尾部分

时间复杂度:O(n)

class Solution(object):
    """
    方法1:倒序输出即可
    """
    def reverseWords(self, s):
        """
        :type s: str
        :rtype: str
        """
        s = s.strip()  # 去除首尾空格
        size = len(s)
        if size <= 1: return s
        lo, hi = size, size
        ans = ''
        for i in range(size - 1 , -1, -1):
            if s[i] == ' ':
                lo = i
                if s[lo+1:hi].strip():              # 加这个条件为了防止单词之间有>=2个空格
                    ans += s[lo+1:hi].strip() + ' '
                hi = lo
            elif i == 0:                            # 这个是为了处理最开始的那个单词
                ans += s[:hi].strip()
            else:
                continue
        return ans

        """
        方法2:双指针法--跟方法1差不多,思路更加清晰一些
        """
        s = s.strip()
        size = len(s)
        if size <= 1: return s
        lo, hi = size, size
        ans = []
        while i >= 0:
            while i >= 0 and s[i] != ' ': i -= 1
            ans.append(s[i+1, j+1])
            while s[i] == ' ': i -= 1
            j = i
        return ' '.join(ans)

面试题58-II:左旋转字符串

题目:字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

基本思路:主要考察三次翻转

1. 将s看成两部分s[:2]s[2:],然后分别翻转这两部分,此时s变为s = "bagfedc"

2. 再将现在的s进行翻转,变成s = "cdefgab"

class Solution(object):
    def reverseLeftWords(self, s, n):
        """
        :type s: str
        :type n: int
        :rtype: str
        """
        return s[n:]+s[:n]

    """三次翻转法"""
    def reverseLeftWords(self, s, n):
        """
        :type s: str
        :type n: int
        :rtype: str
        """
        size = len(s)
        if size <= 1: return s
        s = list(s)
        def reverse(start, end):
            if start >= end: return
            while start < end:
                s[start], s[end] = s[end], s[start]
                start += 1
                end -= 1
        reverse(0, n-1)
        reverse(n, size-1)
        reverse(0, size-1)
        return ''.join(s)

Leetcode02:两数相加(链表)

==>以下题目类似题 || Leetcode415: 字符串相加(大数相加)|| Leetcode45:大数相乘

题目:给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 输出:7 -> 0 -> 8 原因:342 + 465 = 807

基本思路:维护一个进位的标记count;位数不够的用0补上;tmp % 10作为当前位置的值;tmp // 10作为进位的值;

class Solution02(object):
    """
    空间复杂度:O(1)
    时间复杂度:O(m+n)
    """
    def addTwoNumbers(self, l1, l2):
        """
        :type l1: ListNode
        :type l2: ListNode
        :rtype: ListNode
        """
        ans = ListNode(0)
        pre = ans
        count = 0
        while l1 or l2:
            m = l1.val if l1 else 0
            n = l2.val if l2 else 0
            tmp = m + n + count
#             print('m = %d and n = %d and tmp = %d' % (m, n, tmp))
            val = tmp % 10
            count = tmp // 10
            new = ListNode(val)
            ans.next = new
            ans = ans.next
            if l1: l1 = l1.next
            if l2: l2 = l2.next 
        if count == 1: ans.next = ListNode(1)
        return pre.next 

Leetcode415: 字符串相加(大数相加)

==>下一个题目类似题

class Solution(object):
    def addStrings(self, num1, num2):
        """
        :type num1: str
        :type num2: str
        :rtype: str
        """
        i, j, carry = len(num1) - 1, len(num2) - 1, 0 # carry表示是否进位
        res = ''
        while i >= 0 or j >= 0:
            n1 = int(num1[i]) if i >= 0 else 0
            n2 = int(num2[j]) if j >= 0 else 0
            tmp = n1 + n2 + carry
            carry = tmp / 10
            res = str(tmp % 10) + res
            i -= 1
            j -= 1
        return '1' + res if carry else res

Leetcode45:大数相乘

题目:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

示例输入: num1 = "123", num2 = "456" ;输出: "56088

class Solution(object):
    def multiply(self, num1, num2):
        """
        :type num1: str
        :type num2: str
        :rtype: str
        """
        size1, size2 = len(num1), len(num2)        
        ans = [0 for _ in range(size1 + size2)]
        for i in range(size1-1, -1 ,-1):
            for j in range(size2-1, -1, -1):
                tmp = int(num1[i]) * int(num2[j]) + ans[i + j + 1] # 加上原本位置的值
                ans[i + j + 1] = tmp % 10 # 这是靠后的位置
                ans[i + j] += tmp // 10   # 这是靠前的位置, 如果[i + j]位置上的值 > 9, 在这个位置变为[i+j+1]的时候会被ans[i + j + 1] = tmp % 10这一句代码处理
        ans = list(map(str, ans))
        for i in range(size1 + size2):
            if ans[i] != '0':
                return ''.join(ans[i:])
        return '0'

Leetcode344:反转字符串||首尾双指针

基本思路:首尾双指针

class Solution(object):
    def reverseString(self, s):
        """
        :type s: List[str]
        :rtype: None Do not return anything, modify s in-place instead.
        """
        if len(s) >= 2:
            i, j = 0, len(s) - 1
            while i < j:
                s[i], s[j] = s[j], s[i]
                i += 1
                j -= 1

其他:字符串数字转换为INT(不能用int函数)

基本思路:利用ord()函数,与ord('0')比较

class Solution(object):
    def strToInt(s):
        size = len(s)
        ans = 0
        for i in range(size):
            tmp = ord(s[i]) - ord('0')
            ans = ans * 10 + tmp
        return ans

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值