솔루션: 부분 문자열 제거의 최대 점수(버전 2)
19213 단어 pythonalgorithmsjavajavascript
참고: 이것은 이 문제에 대한 솔루션 게시물의 두 번째 버전입니다. 이것이 더 나은 솔루션이지만 .
Leetcode 문제 #1717(중간): 부분 문자열 제거의 최대 점수
설명:
문자열
s
과 두 개의 정수x
및 y
가 제공됩니다. 두 가지 유형의 작업을 여러 번 수행할 수 있습니다."ab"
을 제거하고 x점을 얻습니다."ab"
에서 "cabxbae"
를 제거하면 "cxbae"
가 됩니다."ba"
을 제거하고 점수y
를 얻습니다."ba"
에서 "cabxbae"
를 제거하면 "cabxe"
가 됩니다.s
에 위의 연산을 적용한 후 얻을 수 있는 최대 점수를 반환합니다.예:
예 1:
입력:
s = "cdbcbbbaaabab", x = 4, y = 5
산출:
19
설명:
"cdbcbbbaaaab"에서 밑줄이 그어진 "ba"를 제거합니다. 이제 s = "cdbcbbbaaab"이고 5점이 점수에 추가됩니다. "cdbcbbaaab"에서 밑줄이 그어진 "ab"를 제거합니다. 이제 s = "cdbcbbaa"이고 4점이 추가됩니다. "cdbcbbaa"에 밑줄이 그어진 "ba"를 제거합니다. 이제 s = "cdbcba"이고 5점이 점수에 추가됩니다. "cdbcba"에 밑줄이 그어진 "ba"를 제거합니다.지금, s = "cdbc"및 5점이 점수에 추가됩니다. 총점 = 5 + 4 + 5 + 5 = 19입니다.
예 2:
입력:
s = "aabbaaxybbbaabb", x = 5, y = 4
산출:
20
제약:
1 <= s.length <= 10^5
1 <= x, y <= 10^4
s
는 영문 소문자로 구성되어 있습니다. 아이디어:
참고: 이것은 이 문제에 대한 두 번째 솔루션 게시물입니다. 나는 여전히 the other solution이 멋진 접근 방식이라고 생각하지만 이 방식이 확실히 더 효율적이고 따르기 쉽습니다.
이 문제에 대해 쉽게 깨달을 수 있는 것 중 하나는 문자열을 덩어리로 나눌 수 있다는 것입니다. "a"와 "b"의 연속 세트만 의미가 있으며, 이 두 문자가 아닌 다른 문자를 볼 때마다 한 세그먼트를 효과적으로 종료하고 다른 세그먼트가 시작되기를 기다립니다.
우리가 상당히 쉽게 깨달을 수 있는 또 다른 것은 우리가 어떤 패턴이 더 가치가 있는지 탐욕스럽게 우선순위를 정해야 한다는 것입니다. 일을 더 쉽게 하기 위해 어떤 패턴이 더 높은 값을 갖는지에 따라 일부 변수 스왑을 메인 코드에 접두사로 붙일 수 있습니다. 이 게시물의 나머지 부분에서는 "ab"> "ba", 따라서 = "a"및 b = "b"라고 가정할 수 있습니다.
""와 "b"가 혼합된 세그먼트를 고려하면 해당 세그먼트를 통과하고 더 나은 패턴에 대한 모든 일치 항목을 설명하는 데 문제가 거의 없습니다. 나중의 b와 일치시키기 위해 현재 진행 상황보다 바로 뒤에 있는 a가 몇 개인지 계속 추적해야 합니다.
그러나 가능한 한 X 패턴을 일치시킨 후 Y 패턴을 일치시키는 것은 어떻게 처리합니까? 이에 대한 답을 얻으려면 수정된 문자열이 어떻게 생겼는지 생각해야 합니다.
segment = "bbaababbaa" // initial segment
segment = "bbaa" // after pulling out all "ab" patterns
segment = "bbbbabababaaabababaaaabababaaa" // initial segment
segment = "bbbbaaaaaaaa" // after pulling out all "ab" patterns
가능한 모든 "ab"패턴을 일치시킨 후 유사한 모양의 나머지 세그먼트가 항상 남게 된다는 것을 알 수 있습니다. 다수의 b 다음에 다수의 a가 옵니다. 여기에서 a와 b 사이에 가장 작은 수만큼 "ba"일치를 만들 수 있습니다.
그런 다음 각 세그먼트의 끝에 도달하면 저장소를 지우는 것을 기억해야 합니다.
구현:
다른 언어와 달리 Java에는 변수 내용을 교환하는 편리한 방법이 없습니다.
S의 끝을 지나서 반복을 실행하거나, 마지막 세그먼트가 S의 끝까지 올라갈 경우를 대비하여 최종 Y 일치를 반환 값에 추가해야 합니다.
자바스크립트 코드:
var maximumGain = function(S, X, Y) {
let len = S.length, ans = 0, a = "a", b = "b"
if (Y > X) [a,b,X,Y] = [b,a,Y,X]
let aStore = 0, bStore = 0
for (let i = 0, c = S[i]; i <= len; c = S[++i])
if (c === a) aStore++
else if (c === b)
if (aStore) ans += X, aStore--
else bStore++
else ans += Y * Math.min(aStore, bStore), aStore = bStore = 0
return ans
};
파이썬 코드:
class Solution:
def maximumGain(self, S: str, X: int, Y: int) -> int:
a,b, ans, aStore,bStore = "a","b", 0, 0,0
if Y > X: a,b,X,Y = b,a,Y,X
for c in S:
if c == a: aStore += 1
elif c == b:
if aStore:
ans += X
aStore -= 1
else: bStore += 1
else:
ans += Y * min(aStore, bStore)
aStore,bStore = 0,0
return ans + Y * min(aStore, bStore)
자바 코드:
class Solution {
public int maximumGain(String S, int X, int Y) {
char a = 'a', b = 'b';
int ans = 0, aStore = 0, bStore = 0;
if (Y > X) {
char ctemp = a;
a = b;
b = ctemp;
int itemp = X;
X = Y;
Y = itemp;
}
for (char c: S.toCharArray())
if (c == a) aStore++;
else if (c == b)
if (aStore > 0) {
ans += X;
aStore--;
} else bStore++;
else {
ans += Y * Math.min(aStore, bStore);
aStore = bStore = 0;
}
return ans + Y * Math.min(aStore, bStore);
}
}
C++ 코드:
class Solution {
public:
int maximumGain(string S, int X, int Y) {
char a = 'a', b = 'b';
int ans = 0, aStore = 0, bStore = 0;
if (Y > X) swap(a,b), swap(X,Y);
for (char c: S)
if (c == a) aStore++;
else if (c == b)
if (aStore > 0) ans += X, aStore--;
else bStore++;
else ans += Y * min(aStore, bStore), aStore = bStore = 0;
return ans + Y * min(aStore, bStore);
}
};
Reference
이 문제에 관하여(솔루션: 부분 문자열 제거의 최대 점수(버전 2)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/seanpgallivan/solution-maximum-score-from-removing-substrings-ver-2-58h1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)