public static int minLength(String s) {
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
if(stack.empty()) stack.push(s.charAt(i));
else {
if((stack.peek() == 'A' && s.charAt(i) == 'B') || (stack.peek() == 'C' && s.charAt(i) == 'D')) stack.pop();
else stack.push(s.charAt(i));
}
}
return stack.size();
}
public class Solution {
public int MinLength(string s) {
Stack<char> qr = new Stack<char>();
for (int i = 0; i < s.Length; i++)
{
if (qr.Count > 0)
{
if ((s[i] == 'B' && qr.Peek() == 'A') || (s[i] == 'D' && qr.Peek() == 'C'))
{
qr.Pop();
continue;
}
}
qr.Push(s[i]);
}
return qr.Count;
}
}
class Solution {
public int minLength(String s) {
int len = s.length() - 1;
while(s.length() != len) {
len = s.length();
s = s.replace("AB", "");
s = s.replace("CD", "");
}
return s.length();
}
}
class Solution {
const AB = 'AB';
const CD = 'CD';
/**
* @param String $s
* @return Integer
*/
function minLength($s) {
while (strpos($s, self::AB) !== false || strpos($s, self::CD) !== false) {
$s = str_replace([self::AB, self::CD], '', $s);
}
return strlen($s);
}
}
class Solution:
def minLength(self, s: str) -> int:
stack = []
for c in s:
if c == 'B' and stack and stack[-1] == 'A':
stack.pop()
elif c == 'D' and stack and stack[-1] == 'C':
stack.pop()
else:
stack.append(c)
return len(stack)
class Solution {
public:
int minLength(string s) {
stack<char> myStack;
for (int i = 0; i < s.length(); i++){
if (myStack.empty()){
myStack.push(s[i]);
}else{
if ((myStack.top() == 'A' and s[i] == 'B') || (myStack.top() == 'C' and s[i] == 'D')){
myStack.pop();
}else{
myStack.push(s[i]);
}
}
}
return myStack.size();
}
};
class Solution {
func minLength(_ s: String) -> Int {
var stack:[Character] = []
let map = [Character("B"):Character("A"), Character("D"):Character("C")]
for c in s {
if let mapC = map[c] {
if let last = stack.last, last == mapC {
stack.removeLast()
continue
}
}
stack.append(c)
}
return stack.count
}
}
class Solution {
public int minLength(String s) {
Stack<Character> stack = new Stack();
int remove = 0;
for(char c:s.toCharArray()){
if(!stack.isEmpty()){
if (c==stack.peek()){
stack.pop();
remove+=2;
continue;
}
}
if(c=='A')
stack.add('B');
else if(c=='C')
stack.add('D');
else
stack.clear();
}
return s.length() - remove;
}
}
class Solution {
public int minLength(String s) {
Stack<Character> stack = new Stack();
stack.add('Z');
for(char c:s.toCharArray()){
if(c=='B' && stack.peek()=='A'||
c=='D' && stack.peek()=='C')
stack.pop();
else
stack.add(c);
}
return stack.size()-1;
}
}
class Solution {
public int minLength(String s) {
int n = s.length();
int res = n;
int l = 0;
int r = 1;
boolean[] removed = new boolean[n];
while (r < n) {
char lc = s.charAt(l);
char rc = s.charAt(r);
if ((lc == 'A' && rc == 'B') || (lc == 'C' && rc == 'D')) {
res -= 2;
removed[l] = true;
removed[r] = true;
while (l >= 0 && removed[l] == true) {
l--;
}
r++;
if (l < 0) {
l = r;
r++;
}
} else {
l++;
while (removed[l] == true) {
l++;
}
r = l + 1;
}
}
return res;
}
}
class Solution {
public int minLength(String s) {
int n = s.length();
char[] stack = new char[n];
int peek=-1;
for(char c:s.toCharArray()){
if(peek!=-1){
if((stack[peek] == 'A' && c=='B') || (stack[peek] == 'C' && c=='D') ) {
peek--;
continue;
}
}
stack[++peek] = c;
}
return peek+1;
}
}
Mạt vậnbài hôm này là bài ez àJava:class Solution { public int minLength(String s) { int n = s.length(); int res = n; int l = 0; int r = 1; boolean[] removed = new boolean[n]; while (r < n) { char lc = s.charAt(l); char rc = s.charAt(r); if ((lc == 'A' && rc == 'B') || (lc == 'C' && rc == 'D')) { res -= 2; removed[l] = true; removed[r] = true; while (l >= 0 && removed[l] == true) { l--; } r++; if (l < 0) { l = r; r++; } } else { l++; while (removed[l] == true) { l++; } r = l + 1; } } return res; } }. ẩn độ khó đi r code hoa lá hẹ vào xem mấy bác code lổ lão![]()
![]()

class Solution {
public:
int minLength(string s) {
auto stack = std::vector<char>();
for (auto& c : s) {
if (stack.empty()) { stack.push_back(c); continue; }
if ((c == 'B' && stack.back() == 'A') || (c == 'D' && stack.back() == 'C')) { stack.pop_back(); }
else stack.push_back(c);
}
return stack.size();
}
};
2 pointer chi cho cực z Mao huynhbài hôm này là bài ez àJava:class Solution { public int minLength(String s) { int n = s.length(); int res = n; int l = 0; int r = 1; boolean[] removed = new boolean[n]; while (r < n) { char lc = s.charAt(l); char rc = s.charAt(r); if ((lc == 'A' && rc == 'B') || (lc == 'C' && rc == 'D')) { res -= 2; removed[l] = true; removed[r] = true; while (l >= 0 && removed[l] == true) { l--; } r++; if (l < 0) { l = r; r++; } } else { l++; while (removed[l] == true) { l++; } r = l + 1; } } return res; } }. ẩn độ khó đi r code hoa lá hẹ vào xem mấy bác code lổ lão![]()
![]()
Java:class Solution { public int minLength(String s) { int n = s.length(); char[] stack = new char[n]; int peek=-1; for(char c:s.toCharArray()){ if(peek!=-1){ if((stack[peek] == 'A' && c=='B') || (stack[peek] == 'C' && c=='D') ) { peek--; continue; } } stack[++peek] = c; } return peek+1; } }

trình còi ti toe nó v đó2 pointer chi cho cực z Mao huynh![]()
đúng là ngọa hổ tàng long mà, 2 pointer nhìn rối rắm vậy chứ chạy nhanh hơn stacktrình còi ti toe nó v đó![]()

ví dụ đi fenHôm nay bận rồi ko chơi, nhưng em có thắc mắc có mấy bài thấy dùng cách sort thấy chạy nhanh hơn dùng loop.
Các cao nhân giải thích chút được ko?
Hôm nay bận rồi ko chơi, nhưng em có thắc mắc có mấy bài thấy dùng cách sort thấy chạy nhanh hơn dùng loop.
Các cao nhân giải thích chút được ko?
Như tên suggest: Time Complexity => Độ phức tạp (về) thời gian.
Nó đo độ phức tạp của một thuật toán về mặt thời gian, không phải đo thời gian chạy thực tế.
Dĩ nhiên cái độ phức tạp này nó có tương quan tuyến tính với thời gian thực tế. Với dân Engineer thì có thể quan tâm 2 ý sau:
1. Tồn tại một số N để với mọi input kích thước s >= N: O(n) luôn chạy chậm hơn O(1)
=> Tức là nếu input s < N: O(n) có thể nhanh hơn O(1)
Vậy mình chỉ nên consider đến độ phức tạp khi input của bài toán đủ lớn, còn nếu input nhỏ thì cái mình cần quan tâm hơn là độ phức tạp triển khai (tốn bao nhiêu não để code ra) của bài toán.
Nhưng nói như trên cũng bằng thừa, ai biết cái N đủ lớn là bao nhiêu. Với lại trên đời không chỉ có O(1), O(n). Còn O(n^2), O(logn) các kiểu thì sao ? Điều này dẫn đến ý thứ 2.
2. Time Complexity tỉ lệ thuận với Actual Running Time (ART).
Chỗ này có nghĩa là nếu 1 thuật toán có độ phức tạp là O(f(n)), thì khi input của bài toán tăng gấp n lần, ART cũng sẽ tăng gấp f(n) lần.
Như vậy nếu ta đo ART của 1 thuật toán trên 1 input vừa đủ nhỏ (không quá nhỏ như n = 1, 2 thì dễ bị bias). Ta có thể tính toán được ART của nó trên các input lớn hơn mà không cần phải test thực tế.
- Ví dụ, có 3 thuật toán A, B, C có độ phức tạp là O(1), O(n) và O(n^2)
- Khi chạy với input n = 100: cả 3 đều mất tầm 1ms
- Vậy khi chạy với input gấp 5 lần, n = 500, ta có thể ước lượng:
- Thuật toán A sẽ vẫn chạy mất tầm 1ms
- Thuật toán B sẽ chạy mất tầm 5ms
- Thuật toán C sẽ chạy mất tầm 25ms
Đồng thời ngược lại, nếu mình có 1 ART mong muốn, ta có thể tính được lượng input tối đa mà thuật toán có thể xử lý. Ví dụ:
- Ví dụ, có 3 thuật toán A, B, C có độ phức tạp là O(n), O(logn) và O(n^2)
- Khi chạy với input n = 100:
- A mất 10ms
- B mất 200ms
- C mất 2ms
- Mong muốn là thuật toán phải trả ra kết quả trong tối đa 1s = 1000ms
- A sẽ xử lý được input tối đa n = 100*(1000 / 10) = 10k
- B sẽ xử lý được input tối đa n = 100*(2^(1000 / 200)) = 3200
- C sẽ xử lý được input tối đa n = 100*(sqrt(1000 / 2)) = 2236
- Vậy có thể kết luận, với mức ART <= 1s. Thuật toán A với TC O(n) là phù hợp nhất
- Nhẩm tính thêm 1 chút thì với N > 15000 thì thuật toán B sẽ bắt đầu nhanh hơn thuật toán A
VD: dividePlayers , #2491 (Daily 04/10). Lần đầu em submit theo kiểu Arrays.sort O(nlogn) thì thấy chạy 16ms.ví dụ đi fen