我在比赛中被问到这个问题。
给定一个只包含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;
}
答案 0 :(得分:2)
该算法有2个部分,因为我们希望获得等于K的最长字符间隔。
我们已经有一个间隔&gt; = K所以现在我们需要适当地更改一些字符,以便我们贪婪地更改每个第(k + 1)个字符并再次从0开始计数。
现在,如果间隔小于K,我需要在数组上运行一个滑动窗口。在运行这个窗口时,我基本上考虑在这个长度为K的窗口中将所有L's转换为M.但是这会带来增加间隔长度的副作用,因为可能有K在外面所以这个变量(int nec)跟踪那。所以现在我还要考虑将(K长度)窗口之外的两个可能的M转换为L's。
这是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;
}