剑指offer || 字符串

剑指offer || 字符串

剑指offer中有关字符串的题目汇总


面试题5:替换空格

题目:替换空格

​ 请实现一个函数,把字符串中的每个空格替换成“%20”.

输入: 'hello world'

输出:'hello%20world'

代码

#################面试题5#######################
#替换空格  (非剑指offer的解法)
class Solution:
    # s 源字符串
    def replaceSpace(self, s):
        # write code here
        news = ''
        for i in s:
            if i ==' ':
                news += '%23'
            else:
                news += i
        print(news)

测试

################测试1#################
#功能测试
s = Solution()
s.replaceSpace('hello world')

面试题19:正则表达式匹配

题目:正则表达式匹配

​ 请实现一个函数用来匹配包含‘ .’ 和‘*’的正则表达式

代码

#################面试题19#######################
#正则表达式匹配

测试

################测试1#################
# 功能测试

面试题20:表示数值的字符串

题目:表示数值的字符串

​ 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。

例如:'+100','5e2','-123','3.1416','-1E-16'都是表示数字

'12e','1a3.14','1.2.3','+-5','12e+5.4'都不是

思路

表示字符串遵循模式 A[.[B]][e|EC] A [ . [ B ] ] [ e | E C ] 或者 .B[e|EC] . B [ e | E C ]

A A 为数值的整数部分,B为紧跟小数点为数值的小数部分, C C 紧跟着‘e’或‘E’为数值的指数部分

A部分非必须,如果 A A 为空,则B不能为空

A A C前都可以有 + + 开头的 0 0 ~ 9 的数位串,

B B 也是0 ~ 9 9 的数位串,前面不能有+

首先尽可能多地扫描0 ~ 9 9 的数位,小数点前部分是A;遇到小数点开始扫描 B B

遇到e E E ,则开始扫描C

代码

#################面试题20#######################
#表示数值的字符串
def isNumeric(string):
    if not string:
        return 
    if string == '':
        return False
    i = 0
    positionOfPoint = -1
    positionOfE = len(string)
    while i < len(string):
        if string[i] == '.':
            A = string[0:i]
            positionOfPoint = i
            i += 1
        if string[i] == 'e' or string[i] == 'E':
            if positionOfPoint == -1:#说明 无"."
                positionOfE = i
                A = string[:i]
                B = ''
                i += 1
            else:
                positionOfE = i
                i += 1
        i += 1
    B = string[positionOfPoint + 1:positionOfE]
    if positionOfPoint == -1 and positionOfE == len(string):
        #纯整数的情况
        A = string
        B = ''
    C = string[positionOfE+1:len(string)]
    if positionOfE == 0: #第一位元素是E
        return False
    if (A == '' or scanInteger(A)) and (B =='' or scanNumber(B)) and (C =='' or scanInteger(C)):
        return True
    else:
        return False

def scanNumber(string):
    if string == '':
        return False
    i = 0
    while i < len(string):
        if '0' <= string[i] <= '9':
            i+=1
        else:
            return False
    return True

def scanInteger( string):
    L = len(string)
    if string[0] == '-' or string[0]=='+':
        return scanNumber(string[1:L])
    else:
        return scanNumber(string)

测试

################测试1#################
# 功能测试
string = '+123.11e-122'
isNumeric(string)
isNumeric('+1') #测试正数
#return True
isNumeric('-1') #测试正数
#return True
isNumeric('.123') #不包含整数部分
#return True
isNumeric('e123') #
#return False

# 特殊输入测试
isNumeric(None)

面试题38:字符串的排列

题目:正则表达式匹配

​ 输入一个字符串,打印出该字符串中字符的所有排列。

输入:abc

输出:abc、acb、bac、bca、cab、cba

代码

#################面试题19#######################
#正则表达式匹配

测试

################测试1#################
# 功能测试

面试题46:把数字翻译成字符串

题目:把数字翻译成字符串

​ 给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成’a’,1翻译成’b’,25翻译成’z’

​ 一个数字有多种翻译,例如12258有5钟不同的翻译

​ 编程实现一个函数,用来计算一个数字有多少种不同的翻译方法

思路

以12258为例

两种翻译方法

  • 数字1单独翻译成b 剩下数字2258
  • 数字12翻译成m,后面剩下数字258

递归翻译剩下的数字 递归造成重复计算 需要从下往上翻译

f(i)=f(i+1)+g(i,i+1)f(i+2) f ( i ) = f ( i + 1 ) + g ( i , i + 1 ) f ( i + 2 )

f(i) f ( i ) 表示从第 i i 位数字起不同翻译的数目

当第i位和第 i+1 i + 1 位的两位数字拼接起来的数字在 10 10 ~ 25 25 的范围内,函数 g(i,i+1)=1 g ( i , i + 1 ) = 1 ,否则为 0 0

代码

#################面试题46#######################
#把数字翻译成字符串
def GetTranslationCount(number):
    if number < 0:
        return 0
    strNum = str(number)
    length = len(strNum)
    counts = [0] * length
    count = 0
    for i in range(length - 1, -1, -1):
        count = 0
        if i < length - 1:
            count = counts[i + 1]
        else:  # i = length - 1
            count = 1

        if i < length - 1:
            converted = strNum[i:i + 2]
            if '10' <= converted <= '25':
                if i < length - 2:
                    count += counts[i + 2]
                else:  # i = length - 2
                    count += 1
        counts[i] = count
    return counts[0]

测试

################测试#################
# 功能测试
# 只有一位数字
GetTranslationCount(8)
# 包含多位数字
GetTranslationCount(12)
GetTranslationCount(12258)

# 特殊输入测试
# 负数
GetTranslationCount(-8)
# 0
GetTranslationCount(0)
GetTranslationCount(2526)

面试题48:最长不含重复字符的子字符串

题目:最长不含重复字符的子字符串

​ 请从字符串中找出一个最长的不包含重复字符的子字符串,计算最长该子字符串的长度。假设字符串中只包含’a’ ~ ‘z’ 的字符

输入:'arabcacfr'

输出:最长的不包含重复字符的子字符串是'acfr'

思路

动态规划

f(i):以第 i i 个字符为结尾的不包含重复字符的子字符串的最长长度

(1)第i个字符之前没出现过, f(i)=f(i1)+1 f ( i ) = f ( i − 1 ) + 1

(2) ( 2 ) 第i个字符之前已经出现过。

​ 计算第i个字符和它上次出现在字符串中的位置的距离, d d

​ 1、d<=f(i1) 第i个字符上次出现在f(i-1)对应的最长子字符串之中

f(i)=d f ( i ) = d

​ 2、 d>f(i1) d > f ( i − 1 ) 第i个字符上次出现在f(i-1)对应的最长子字符串之前

f(i)=f(i1)+1 f ( i ) = f ( i − 1 ) + 1

代码

#################面试题48#######################
#最长不含重复字符的子字符串

def longestSubstringWithoutDuplication(string):
    curLength = 0
    maxLength = 0
    position = [-1] * 26  # 26个字母
    if not string:
        return None
    for i in range(len(string)):
        preIndex = position[ord(string[i]) - ord('a')]
        if preIndex < 0 or i - preIndex > curLength:
            curLength += 1
        else:
            if curLength > maxLength:
                maxLength = curLength
            curLength = i - preIndex
        position[ord(string[i]) - ord('a')] = i

    if curLength > maxLength:
        maxLength = curLength

    return maxLength

测试

################测试1#################
# 功能测试
# 包含多个字符的字符串
longestSubstringWithoutDuplication('arabcacfr')

# 只有一个字符的字符串
longestSubstringWithoutDuplication('a')

# 所有字符都相同的字符串
longestSubstringWithoutDuplication('aaaa')

# 特殊输入测试
longestSubstringWithoutDuplication(None)

面试题58:翻转字符串

题目一:翻转单词顺序

​ 输入一个英文句子,翻转句子中的单词顺序,但单词内的字符顺序不变。为简单起见,标点符号和普通字母一样处理。

输入:“ I am a student."

输出:student. a am I

代码

#################面试题58#######################
#翻转单词顺序

测试

################测试1#################
# 功能测试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值