Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使最长字符间隔等于K所需的最小操作数_Java_C#_Algorithm_Data Structures_Dynamic Programming - Fatal编程技术网

Java 使最长字符间隔等于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” 以下

我在一次比赛中被问到这个问题。 给定一个只包含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”

以下是我迄今为止尝试过的,但我没有得到正确的输出: 我遍历字符串,每当最长字符数超过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);
    cout
    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
    
    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;
    }