使最长字符间隔等于K所需的最小操作

时间:2018-04-30 18:20:29

标签: java c# algorithm data-structures dynamic-programming

我在比赛中被问到这个问题。 给定一个只包含M和L的字符串,我们可以更改任何" M"到" L"或任何" L"到" M"。此功能的目的是计算我们必须进行的最小更改次数,以达到所需的最长M间隔长度K.
例如,给定S =" MLMMLLM"函数应该返回1.我们可以改变位置4处的字母(从0开始计算)以获得" MLMMMLM",其中字母的最长间隔为" M"正好是三个字符长。

另一个例子,给定S =" MLMMMLMMMM"并且K = 2,函数应该返回2.例如,我们可以修改位置2和7处的字母以获得字符串" MLLMMLMLMM",它满足所需的属性。

这是我到目前为止所尝试过的,但我没有得到正确的输出: 我正在遍历字符串,每当最长字符数超过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;
}

3 个答案:

答案 0 :(得分:2)

该算法有2个部分,因为我们希望获得等于K的最长字符间隔。

  1. 我们已经有一个间隔&gt; = K所以现在我们需要适当地更改一些字符,以便我们贪婪地更改每个第(k + 1)个字符并再次从0开始计数。

  2. 现在,如果间隔小于K,我需要在数组上运行一个滑动窗口。在运行这个窗口时,我基本上考虑在这个长度为K的窗口中将所有L's转换为M.但是这会带来增加间隔长度的副作用,因为可能有K在外面所以这个变量(int nec)跟踪那。所以现在我还要考虑将(K长度)窗口之外的两个可能的M转换为L's。

  3. 这是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;
    }
    

答案 1 :(得分:0)

public void ConfigureServices(IServiceCollection services)
{
    // Add application services.
       services.AddSingleton<IDataAccess, SQLAccess>(opt=> { new SQLAccess(new 
       Settings(){ 
           //Set Settings object properties here

       }); 
   });
}

答案 2 :(得分:0)

更正后的代码:

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;
}