剑指offer || 动态规划

  • Post author:
  • Post category:其他


剑指offer || 动态规划

剑指offer中有关

动态规划

的题目汇总



面试题14:剪绳子


题目:剪绳子

​ 给你一根长度为n的绳子,请把绳子剪成m段(m,n都是整数,n > 1 并且 m > 1), 每段绳子的长度记为k[0],k[1],…,k[m]。请问 k[0] * k[1]* …*k[m]可能的最大乘积是多少?


例子:当绳子的长度是8时,我们把它剪成长度为2、3 、3的三段,此时的最大乘积是18

`


思路

  • 动态规划


代码

#################面试题14#######################
#剪绳子
class Solution:
    def maxProdectAfterCutting_solution(self,length):
        product = []
        if length <2:
            return 0
        elif length == 2:
            return 1
        elif length == 3:
            return 2
        product.extend([0,1,2,3])
        max = 0
        for i in range(4,length+1):
            for j in range(1,i//2+1):
                area = product[j] * product[i-j]
                if max < area:
                    max = area
            product.append(max)
        return max


测试

################测试1#################
#功能测试
s = Solution()
s.maxProdectAfterCutting_solution(5)


面试题42:连续子数组的最大和


题目:连续子数组的最大和

​ 输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)


输入: 数组[1,-2,3,10,-4,7,2,-5],和最大的子数组为[3,10,-4,7,2]


输出:,因此输出该数组的和为18


思路


代码

#################面试题42#######################
#连续子数组的最大和

def FindGreatestSumOfSubArray(Array):
    if not Array:
        return 
    n = len(Array)
    maxSumArrayOfsubArray = [0] *(n+1)
    maxSum = float('-inf')
    for i in range(1,n+1):
        if maxSumArrayOfsubArray[i-1] <= 0:
            maxSumArrayOfsubArray[i] = Array[i-1]
        else:
            maxSumArrayOfsubArray[i] = maxSumArrayOfsubArray[i-1] + Array[i-1]
        if maxSum < maxSumArrayOfsubArray[i]:
            maxSum = maxSumArrayOfsubArray[i]
    return maxSum


测试

################测试1#################
#功能测试
#
Array = [1,-2,3,10,-4,7,2,-5]
result = FindGreatestSumOfSubArray(Array)
print(result)

Array = [-2,-3,-10,-4,-7,-2,-5]
result = FindGreatestSumOfSubArray(Array)
print(result)

Array = [2,3,10,4,7,2,5]
result = FindGreatestSumOfSubArray(Array)
print(result)


面试题47:礼物的最大价值


题目:礼物的最大价值

​ 在一个m*n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值,可以从棋盘的左上角开始拿格子里的礼物,并每次向左或右移动一格,直到到达棋盘的右下角。给定棋盘及其礼物,计算最多能拿到多少价值的礼物


例如:

1 10 3 8

12 2 9 6

5 7 4 11

3 7 16 5`


思路

  • 动态规划求解







  • f




    (


    i


    ,


    j


    )


    =


    m


    a


    x


    (


    f




    (


    i





    1


    ,


    j


    )


    ,


    f




    (


    i


    ,


    j





    1


    )


    )


    +


    g




    i


    f




    t


    [


    i


    ,


    j


    ]










    f

    (

    i

    ,

    j

    )

    =

    m

    a

    x

    (

    f

    (

    i

    1

    ,

    j

    )

    ,

    f

    (

    i

    ,

    j

    1

    )

    )

    +

    g

    i

    f

    t

    [

    i

    ,

    j

    ]



代码

#################面试题47#######################
#礼物的最大价值

def getMaxValue_solution1(values):
    if not values:
        return 0
    rows = len(values)
    if not isinstance(values[0], list):
        maxValue = sum(values)
        return maxValue
    else:
        cols = len(values[0])
    if cols == 1:
        maxValue = 0
        for row in range(rows):
            maxValue += values[row][0]
        return maxValue

    maxValues = [[0] * cols] * rows

    for i in range(rows):
        for j in range(cols):
            left = 0
            up = 0
            if i > 0:  # i=0 边界
                up = maxValues[i - 1][j]
            if j > 0:
                left = maxValues[i][j - 1]
            maxValues[i][j] = max(left, up) + values[i][j]
    maxValue = maxValues[rows - 1][cols - 1]
    return maxValue


  #########优化#############
# 只用一个一维数组来代替二维数组maxValues
# 该数组前面j个数字分别是当前i行前面j个格子礼物的最大价值
# 之后的数字分别保存i-1行,n-j个格子的礼物的最大价值

def getMaxValue_solution2(values):
    if not values:
        return 0
    rows = len(values)
    if not isinstance(values[0], list):
        maxValue = sum(values)
        return maxValue
    else:
        cols = len(values[0])
    if cols == 1:
        maxValue = 0
        for row in range(rows):
            maxValue += values[row][0]
        return maxValue

    maxValues = [0] * cols

    for i in range(rows):
        for j in range(cols):
            left = 0
            up = 0
            if i > 0:  # i=0 边界
                up = maxValues[j]
            if j > 0:
                left = maxValues[j - 1]
            maxValues[j] = max(left, up) + values[i][j]
    maxValue = maxValues[cols - 1]
    return maxValue


测试

################测试1#################
#功能测试
# 功能测试
# 多行多列的矩阵
values = [[1, 10, 3, 8], [12, 2, 9, 6], [5, 7, 4, 11], [3, 7, 16, 5]]
getMaxValue_solution1(values)

# 一行或一列矩阵
values = [1, 10, 3, 8]  # 一行
getMaxValue_solution1(values)

values = [[1], [10], [3], [8]]  # 一列
getMaxValue_solution1(values)

# 只有一个数字的矩阵
values = [1]
getMaxValue_solution1(values)

# 特殊输入测试
getMaxValue_solution1(None)


##############优化后测试##########
# 功能测试
# 多行多列的矩阵
values = [[1, 10, 3, 8], [12, 2, 9, 6], [5, 7, 4, 11], [3, 7, 16, 5]]
getMaxValue_solution2(values)

# 一行或一列矩阵
values = [1, 10, 3, 8]  # 一行
getMaxValue_solution2(values)

values = [[1], [10], [3], [8]]  # 一列
getMaxValue_solution2(values)

# 只有一个数字的矩阵
values = [1]
getMaxValue_solution2(values)

# 特殊输入测试
getMaxValue_solution2(None)



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


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

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

`输入: 字符串’arabcacfr’


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


思路

动态规划








f




(


i


)










f

(

i

)



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

(1) 第i个字符之前没出现过,







f




(


i


)


=


f




(


i





1


)


+


1










f

(

i

)

=

f

(

i

1

)

+

1


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

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

​ 1、







d




<

=



f




(


i





1


)










d

<=

f

(

i

1

)



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









f




(


i


)


=


d












f

(

i

)

=

d


​ 2、







d




>


f




(


i





1


)










d

>

f

(

i

1

)



第i个字符上次出现在f(i-1)对应的最长子字符串之前









f




(


i


)


=


f




(


i





1


)


+


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)



版权声明:本文为qq_29737811原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。