获取子字符串位子_Leetcode1278:回文字符串III

0f804e2c7b48ce69a45904c976451e11.png

题目描述

给定一个只包含小写字母的字符串s 和一个正整数k,你需要:

1. 字符串中的某些字母改变为其他的小写字母;

2. 将s分成k个非空的子字符串,使得每个子字符串都是回文。

返回:字符串s中最少改变的字母个数

57195018267365db520996b10c6c2035.png

问题分析

1. 问题的结果是从字符串s中改变的最小字母使得分开成k个非空的字符串时,k个非空字符串都是回文;则可以设返回结果为 aaDivide(s,k),同时s可以变换为s的大小nStrSize,则可以得到aaDivide(nStrSize-1,k);

2. s字符串中分开为k个子字符串时,每个字符串都是回文,所以假设某个子字符串为字符串从i位置到j位置的话,最小需要改变的字母个数为aaChangeNum(i,j)

3. 在确定好上面的两个递推的变量后,开始寻找递推关系和边界条件

4. 对于aaChangeNum来说:

当i==j时,aaChangeNum(i,j)=0(因为单个字母本身就是回文);当i==j-1时,如果s[i]==s[j],则aaChangeNum(i,j)=0,否则aaChangeNum(i,j)=1;

从这个地方也可以分析出递推关系:

当s[i]==s[j]时,aaChangeNum(i,j)=aaChangeNum(i+1,j-1),否则aaChangeNum(i,j)=aaChangeNum(i+1,j-1) +1

5. 对于aaDivide来说:

当k=1时,aaDivide(n,1) = aaChangeNum(0,n)

aaDivide(nStrSize-1,k)= aaDivide(m,k-1)+aaChangeNum(m+1,nStrSize-1) 对于m从k-1到nStrSize-2

代码实现

class Solution {public: int palindromePartition(string s, int K) { vector> aaDivide(101,vector(101,100)); vector> aaChangeNum(101,vector(101,101)); for(int i = 0; i < s.size(); i++) { aaChangeNum[i][i] = 0; } for(int i = 0; i < s.size()-1;i++) { if(s[i] == s[i+1]) aaChangeNum[i][i+1] = 0; else aaChangeNum[i][i+1] = 1; }  for(int k = 2; k < s.size(); k++) { for(int i = 0; i < s.size(); i++) { if(i+k>=s.size()) continue; int j = i + k; aaChangeNum[i][j] = aaChangeNum[i+1][j-1]; if(s[i]!=s[j]) aaChangeNum[i][j] = aaChangeNum[i+1][j-1] + 1; } }  for(int j = 0; j < s.size(); j++) { aaDivide[j][1] = aaChangeNum[0][j]; }  for(int k = 2; k <= K; k++ ) { for(int j = 1; j < s.size(); j++) { aaDivide[j][k] = j+1; for(int l = 0; l <= j; l++) { aaDivide[j][k] = min(aaDivide[l][k-1] + aaChangeNum[l+1][j], aaDivide[j][k]); } } } return aaDivide[s.size()-1][K];  }};

总结分析

本题还是在leetcode中算是很复杂的题目了,我在周末的刷题考试时也没有完全写完;但是通过上面的分析过程后,发现其实也没有那么困难。而重点在于找好自变量(就像初中时解答应用题时,需要好未知量一样),然后再自变量的基础上,将需要求解的问题和自变量关联起来(就像初中时解答应用题时,需要列好方程),此题中不同的是多了自变量自身的迭代关系和边界条件。

对于迭代关系和边界条件,在确认好自变量后,可以先从边界条件开始,有特定到一般来进行推到递推关系,也在一定程度上能够很快的获取到迭代关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值