Java 使最长字符间隔等于K所需的最小操作数
我在一次比赛中被问到这个问题。 给定一个只包含M和L的字符串,我们可以将任意“M”改为“L”,或将任意“L”改为“M”。此函数的目的是计算我们必须进行的最小更改次数,以获得所需的最长M间隔长度K。Java 使最长字符间隔等于K所需的最小操作数,java,c#,algorithm,data-structures,dynamic-programming,Java,C#,Algorithm,Data Structures,Dynamic Programming,我在一次比赛中被问到这个问题。 给定一个只包含M和L的字符串,我们可以将任意“M”改为“L”,或将任意“L”改为“M”。此函数的目的是计算我们必须进行的最小更改次数,以获得所需的最长M间隔长度K。 例如,给定S=“MLMMLLM”和K=3,函数应返回1。我们可以更改位置4处的字母(从0开始计数)以获得“MLMMMLM”,其中字母“M”的最长间隔正好是三个字符长 例如,给定S=“mlmmmm”和K=2,函数应返回2。例如,我们可以修改位置2和7处的字母,以获得满足所需属性的字符串“mlmm” 以下
例如,给定S=“MLMMLLM”和K=3,函数应返回1。我们可以更改位置4处的字母(从0开始计数)以获得“MLMMMLM”,其中字母“M”的最长间隔正好是三个字符长 例如,给定S=“mlmmmm”和K=2,函数应返回2。例如,我们可以修改位置2和7处的字母,以获得满足所需属性的字符串“mlmm” 以下是我迄今为止尝试过的,但我没有得到正确的输出: 我遍历字符串,每当最长字符数超过K时,我就用L替换m
public static int solution(String S, int K) {
StringBuilder Str = new StringBuilder(S);
int longest=0;int minCount=0;
for(int i=0;i<Str.length();i++){
char curr=S.charAt(i);
if(curr=='M'){
longest=longest+1;
if(longest>K){
Str.setCharAt(i, 'L');
minCount=minCount+1;
}
}
if(curr=='L')
longest=0;
}
if(longest < K){
longest=0;int indexoflongest=0;minCount=0;
for(int i=0;i<Str.length();i++){
char curr=S.charAt(i);
if(curr=='M'){
longest=longest+1;
indexoflongest=i;
}
if(curr=='L')
longest=0;
}
Str.setCharAt(indexoflongest, 'M');
minCount=minCount+1;
}
return minCount;
}
公共静态int解决方案(字符串S,int K){
StringBuilder Str=新的StringBuilder;
int longest=0;int minCount=0;
对于(int i=0;iK){
塞查拉特街(i,‘L’);
minCount=minCount+1;
}
}
如果(curr=='L')
最长=0;
}
if(最长 对于(int i=0;i这个算法有两个部分,因为我们想要得到等于K的最长字符间隔
我们已经有了一个间隔>=K,所以现在我们需要适当地更改一些字符,以便我们贪婪地更改每个(K+1)字符,然后再次从0开始计数
现在,如果间隔小于K,我需要在数组上运行一个滑动窗口。运行此窗口时,我基本上考虑将此长度为K的窗口中的所有L转换为M。但这会带来一个副作用,即增加间隔的长度,因为可能有K的外部,所以此变量(int nec)因此,我还必须考虑将2个可能的m(k长度)窗口转换成L的 。
这里是C++中完整的可运行代码。祝你有个愉快的一天。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector <int> vi;
typedef pair<int, int> ii;
int change(string s, int k) {
// handling interval >= k
bool flag = false;
int ans = 0;
int cnt = 0;
for(int i=0; i<s.size(); i++) {
if(s[i] == 'M') cnt++;
else cnt = 0;
if(cnt == k) flag = true;
if(cnt > k) s[i] = 'L', ans++, cnt = 0;
}
if(flag) return ans;
// handling max interval < k
// If the interval is too big.
if(k > s.size()) {
cerr << "Can't do it.\n"; exit(0);
}
// Sliding window
cnt = 0;
for(int i=0; i<k; i++) {
if(s[i] == 'L') cnt++;
}
ans = cnt + (s[k] == 'M'); // new edit
int nec = 0; // new edit
for(int i=k; i<s.size(); i++) {
if(s[i-k] == 'L') cnt--;
if(s[i] == 'L') cnt++;
nec = 0;
if(i-k != 0 && s[i-k-1] == 'M')
nec++;
if(i < s.size()-1 && s[i+1] == 'M')
nec++;
ans = min(ans, cnt + nec);
}
return ans;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
string s;
int k;
cin >> s >> k;
int ans = change(s, k);
cout << ans << "\n";
return 0;
}
#包括
使用名称空间std;
typedef long-long-ll;
typedef向量vi;
第二类;
整数更改(字符串s,整数k){
//处理间隔>=k
布尔标志=假;
int ans=0;
int-cnt=0;
对于(inti=0;ik)s[i]='L',ans++,cnt=0;
}
如果(标记)返回ans;
//处理最大间隔s.size()){
cerr>k;
int ans=变化(s,k);
coutint
过程数据(常量字符*m,整数k)
{
int m_cnt=0,c_cnt=0;
char ch;
常数char*st=m;
int inc_cnt=-1;
int dec_cnt=-1;
而((ch=*m++)!=0){
if(m_cnt++c_cnt))){
inc_cnt=c_cnt;
}
}
else如果(ch='M'){
如果(*st++=='M'){
/*
*失去和获得M不会带来任何变化
*区块中至少有一个L。(c_cnt!=0)
*否则它意味着Ms的延伸
*/
如果(c_cnt 0,“期望c_cnt(%d)>0”,c_cnt);
断言(inc_cnt!=-1,“expect inc_cnt(%d)!=-1”,inc_cnt);
/*失去L,获得M*/
如果(--c_cnt
int
process_data(const char *m, int k)
{
int m_cnt = 0, c_cnt = 0;
char ch;
const char *st = m;
int inc_cnt = -1;
int dec_cnt = -1;
while((ch = *m++) != 0) {
if (m_cnt++ < k) {
c_cnt += ch == 'M' ? 0 : 1;
if ((m_cnt == k) && (
(inc_cnt == -1) || (inc_cnt > c_cnt))) {
inc_cnt = c_cnt;
}
}
else if (ch == 'M') {
if (*st++ == 'M') {
/*
* losing & gaining M carries no change provided
* there is atleast one L in the chunk. (c_cnt != 0)
* Else it implies stretch of Ms
*/
if (c_cnt <= 0) {
c_cnt--;
}
}
else {
ASSERT(c_cnt > 0, "expect c_cnt(%d) > 0", c_cnt);
ASSERT(inc_cnt != -1, "expect inc_cnt(%d) != -1", inc_cnt);
/* Losing L and gaining M */
if (--c_cnt < inc_cnt) {
inc_cnt = c_cnt;
}
}
}
else {
if (c_cnt <= 0) {
/*
* compute min inserts needed to brak the
* stretch to meet max of k.
*/
dec_cnt += (dec_cnt == -1 ? 1 : 0) + ((k - c_cnt) / (k+1));
/*
* take this as a first break and restart
* as any further addition of M should not
* happen. Ignore this L
*/
st = m;
c_cnt = 0;
m_cnt = 0;
}
else if (*st++ == 'M') {
/* losing m & gaining l */
c_cnt++;
}
else {
// losing & gaining L; no change
}
}
}
if (c_cnt <= 0) {
/*
* compute min inserts needed to brak the
* stretch to meet max of k.
*/
dec_cnt += (dec_cnt == -1 ? 1 : 0) + ((k - c_cnt) / (k+1));
}
return dec_cnt != -1 ? dec_cnt : inc_cnt;
}
int
过程数据(常量字符*m,整数k)
{
int m_cnt=0,c_cnt=0;
char ch;
常数char*st=m;
int inc_cnt=-1;
int dec_cnt=-1;
而((ch=*m++)!=0){
if(m_cnt++c_cnt))){
inc_cnt=c_cnt;
}
}
else如果(ch='M'){
如果(*st++=='M'){
/*
*失去和获得M不会带来任何变化
*区块中至少有一个L。(c_cnt!=0)
*否则它意味着Ms的延伸
*/
如果(c_cnt 0,“期望c_cnt(%d)>0”,c_cnt);
断言(inc_cnt!=-1,“expect inc_cnt(%d)!=-1”,inc_cnt);
/*失去L,获得M*/
如果(--c_cnt 如果(c_cnt)您如何处理其他情况?是否存在需要将L替换为M的情况?代码中的位置在哪里?我已编辑代码以包含该条件。但它不是最优的。您所说的最优是什么意思?期望的运行时复杂性是什么?它给出了错误的答案吗?显然有人应该在ML中添加解决方案:)@GaganDeep:你想在这次编码竞赛中作弊吗?-通过编码和ASML降低复杂性?谢谢,但它给出了错误的答案。对于,更改(“MLMMMLMMMM”,2),它返回3,但答案应该是2。对于,更改(“MLMMLLM”,3),它返回3,但答案应该是1。我做了一些更改。你能确认它现在是否正确吗。嗯,在这种情况下可能是错误的吗?:change('MLMM',3);得到1,但预期为2。是的!谢谢你的案例。新的变化。我认为你应该对你的答案添加一些解释。尽管你的解决方案满足了比赛的预期。步行一次。当你步行时,获得要进行的变化的计数,以满足伸展运动中至少K个Ms的计数,并将最小的作为inc_cnt,在同一次步行中,减少c_cnt,当Ms的拉伸超过K时,它将变为负值,对于每个拉伸,找到所需插入的计数并求和。我有一个错误。我应该只在拉伸结束时计算t,
int
process_data(const char *m, int k)
{
int m_cnt = 0, c_cnt = 0;
char ch;
const char *st = m;
int inc_cnt = -1;
int dec_cnt = -1;
while((ch = *m++) != 0) {
if (m_cnt++ < k) {
c_cnt += ch == 'M' ? 0 : 1;
if ((m_cnt == k) && (
(inc_cnt == -1) || (inc_cnt > c_cnt))) {
inc_cnt = c_cnt;
}
}
else if (ch == 'M') {
if (*st++ == 'M') {
/*
* losing & gaining M carries no change provided
* there is atleast one L in the chunk. (c_cnt != 0)
* Else it implies stretch of Ms
*/
if (c_cnt <= 0) {
c_cnt--;
}
}
else {
ASSERT(c_cnt > 0, "expect c_cnt(%d) > 0", c_cnt);
ASSERT(inc_cnt != -1, "expect inc_cnt(%d) != -1", inc_cnt);
/* Losing L and gaining M */
if (--c_cnt < inc_cnt) {
inc_cnt = c_cnt;
}
}
}
else {
if (c_cnt <= 0) {
/*
* compute min inserts needed to brak the
* stretch to meet max of k.
*/
dec_cnt += (dec_cnt == -1 ? 1 : 0) + ((k - c_cnt) / (k+1));
/*
* take this as a first break and restart
* as any further addition of M should not
* happen. Ignore this L
*/
st = m;
c_cnt = 0;
m_cnt = 0;
}
else if (*st++ == 'M') {
/* losing m & gaining l */
c_cnt++;
}
else {
// losing & gaining L; no change
}
}
}
if (c_cnt <= 0) {
/*
* compute min inserts needed to brak the
* stretch to meet max of k.
*/
dec_cnt += (dec_cnt == -1 ? 1 : 0) + ((k - c_cnt) / (k+1));
}
return dec_cnt != -1 ? dec_cnt : inc_cnt;
}