第七周(Dynamic Programming)

第七周(Dynamic Programming)

目录:

  • 本周完成题目
  • 主要过程思路
  • 相关代码
  • 感想与总结

一、本周完成题目

本周共完成2道题目,1道Medium,1道Hard。主要是针对于本周所学的Dynamic Programming选择了一些题目进行练习。

具体完成题目及难度如下表:

#TitleDifficulty
72Edit DistanceHard
413Arithmetic SlicesMedium

题目内容

1、Edit Distance 
Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

You have the following 3 operations permitted on a word:
a) Insert a character
b) Delete a character
c) Replace a character

题目大意:给定两个单词,判断从单词1变化到单词2最少需要多少步(最小距离)。变化的方式有3种,插入、删除、替换字母。

2、Arithmetic Slices 
A sequence of number is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same.

For example, these are arithmetic sequence:

    1, 3, 5, 7, 9
    7, 7, 7, 7
    3, -1, -5, -9

The following sequence is not arithmetic.

    1, 1, 2, 5, 7

A zero-indexed array A consisting of N numbers is given. A slice of that array is any pair of integers (P, Q) such that 0 <= P < Q < N.

A slice (P, Q) of array A is called arithmetic if the sequence:
A[P], A[p + 1], …, A[Q - 1], A[Q] is arithmetic. In particular, this means that P + 1 < Q.

The function should return the number of arithmetic slices in the array A.

题目大意:判断当前元素中连续的数字中,等差数列的数量。等差数列长度≥3。

二、主要过程思路

本周的题目使用到了Dynamic Programming的思想,简单来说需要从逐步到整体,动态操作最后得到需要的结果。下面是两道题目的主要思路。

1、Edit Distance:

这道题是一个比较典型的动态规划问题。
设置一个新的状态数组dp。
dp[i][j] 代表了word1的前i个字母和word2前j个字母的最小距离。
所以dp[1][0]-dp[l1][0]大小分别为1到l1(dp[0][l2]同理)
下面从第一个字母开始对于数组进行动态变化,如果对应字母相同,则可以直接取dp[i-1][j-1]的值。如果不相同,就要判断3种操作哪一种距离最小。3种操作分别相当于如下对于dp的操作:
a) 插入: dp[i][j]=dp[i][j-1]+1
b) 删除: dp[i][j]=dp[i-1][j]+1
c) 替换: dp[i][j]=dp[i-1][j-1]+1
最后根据设定的含义,只要取dp[l1][l2]就是最后要求的最小距离。

2、Arithmetic Slices:

这一题需要用到一点等差数列的相关知识。等差数列数字从3个变成4个,会从1种变为3种(增加2),再变为5个数字又会增加3。依次类推,发现每次都在原有的基础上增加1-n种。也就是说,可以根据这一特点从3个数字的情况开始,根据队列中等差数列的长度判断符合情况的有多少种。
具体而言,定义一个add,如果连续三个数字符合等差数列规则,add++并加入count中。如果发现等差数列在某个数字处断掉,则令add归零,重新开始计算等差数列长度。直到队尾返回结果。

三、相关代码

Edit Distance


class Solution {
public:
    int minDistance(string word1, string word2) {
        int l1=word1.size();
        int l2=word2.size();
        vector<vector<int> > dp(l1 + 1, vector<int> (l2 + 1, 0));
        for (int i = 1; i <= l1; i++)
            dp[i][0] = i;
        for (int j = 1; j <= l2; j++)
            dp[0][j] = j;
        for(int i=1;i<=l1;i++){
             for(int j=1;j<=l2;j++){
                 if (word1[i - 1] == word2[j - 1]){
                    dp[i][j] = dp[i - 1][j - 1];
                 }
                 else{
                     dp[i][j]=1+min(min(dp[i-1][j],dp[i-1][j-1]),dp[i][j-1]);
                 }
             }
        }
        return dp[l1][l2];
    }
};

Arithmetic Slices

class Solution {
public:
    int numberOfArithmeticSlices(vector<int>& A) {
        int n=A.size();
        if(n==0)  return 0;
        int count=0;
        int add=0;   
        for(int i=2;i<n;i++){
            if((A[i]-A[i-1])==(A[i-1]-A[i-2])){
                count+=++add;
            }else{
                add=0;
            }       
        }
        return count;
    }
};

四、感想与总结

本周随便选择了两道Dynamic Programming分类下的题目。借鉴了一些别人的思想,不过第一道的类似思想在之前的brust balloon中已经涉及到。
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。
总体而言动态规划比较灵活,需要在具体问题中具体分析灵活运用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值