thảo luận Leetcode + Codeforces, Competitive programming contest. Đường tới Guardian + Candidate Master.

  • Người tạo chủ đề Người tạo chủ đề freedom.9
  • Ngày bắt đầu Ngày bắt đầu
Dạo này bị Leetcode chơi quá, thôi dời mục tiêu cuối năm lên lại 2k2 vậy :too_sad:
Rõ ràng dạo này code kinh hơn xưa, giải hard nhiều hơn, biết nhiều chiêu thức hơn mà rating lại ko bằng
4gmOAMB.gif


via theNEXTvoz for iPhone
 
1756953066443.png

Q2 cứ nghĩ backtracking ko pass, gục ngã =(( chắc phải 2 năm rồi mới có cái rating khủng khiếp thế này đm =(( Đúng cái contest thứ 100 nữa chứ :ah:
 
:v lại gặp dp digit :> lỏ rồi, bài 3 không độc unique nên handle cả trường hợp không unique luôn @@
 
bài cuối có ý tưởng chia làm 2 phase, phase 1 là số bit bé hơn n -> dễ tự code, phase 2 là số bit bằng n và bé hơn n -> vibe code
 
Bài 3 khoai hơn chứ bài 4 tinh ý xử lý dễ hơn kha khá
Lấy các chuỗi thỏa mãnđộ dài bit nhỏ hơn (ez)
Với các chuỗi bằng độ dài bit, lấy các chuỗi có nửa bit đầu < nửa bit đầu của n
Với chuỗi palindrome có nửa bit đầu = nửa bit đầu của n, check xem có <=n hay k
Ban đầu xử lý ngu đoạn độ dài bit ngang nhau thành cmn căn n
 
Q3 của em :v không đọc kĩ đề nên em handle thừa trường hợp
Dùng monotoic stack để đếm số cặp cỏ lr bằng nhau/ 1 trong 2 là max của cả đoạn (đếm xuôi và đếm ngược). Khó ở chỗ khi đếm xuôi/ngược thì trường hợp lr bằng nhau đều bị tính. Nên lúc đếm xuôi thì điều kiện của monotic không có equal (tìm số strictly lớn hơn). Còn đếm ngược thì cho phép equal -> chỉ tính 1 lần.
Do unique nên đếm xuôi/ ngược thì không trùng :> ngu quá
Java:
class Solution {
    public long bowlSubarrays(int[] nums) {
        int[] reverse = new int[nums.length];
        for (int i = 0; i < nums.length; i += 1) {
            reverse[nums.length - 1 - i] = nums[i];
        }

        return count(nums) + countEqual(reverse);
    }

    public long countEqual(int[] nums) {
        int[] leftBigger = biggerFromLeftEqual(nums);
        int[] countSameEqual = counterSameNumber(nums);

        long answer = 0;
        int n = nums.length;
        for (int i = 0; i < n; i += 1) {
            int left = leftBigger[i];
            int countNumBigger = countSameEqual[left];

            if (i - left >= 2) {
                answer += countNumBigger;
            }
        }

        return answer;
    }

    public long count(int[] nums) {
        int[] leftBigger = biggerFromLeft(nums);
        int[] countSameEqual = counterSameNumber(nums);

        long answer = 0;
        int n = nums.length;
        for (int i = 0; i < n; i += 1) {
            int left = leftBigger[i];
            int countNumBigger = countSameEqual[left];

            if (i - left >= 2) {
                answer += countNumBigger;
            }
        }
        System.out.println(answer);

        return answer;
     
    }

    public int[] counterSameNumber(int[] nums) {
        int counter[] = new int[nums.length];
        counter[0] = 1;
        for (int i = 1; i < nums.length; i += 1) {
            if (nums[i] == nums[i - 1]) {
                counter[i] = counter[i - 1] + 1;
            } else {
                counter[i] = 1;
            }
        }

        return counter;
    }
 
    public int[] biggerFromLeftEqual(int[] nums) {
        int[] biggerFromLeft = new int[nums.length];
        Stack<Integer> decreaseOnly = new Stack<>();
        for (int i = 0; i < nums.length; i += 1) {
            while (!decreaseOnly.isEmpty() && nums[decreaseOnly.peek()] < nums[i]) {
                decreaseOnly.pop();
            }

            if (decreaseOnly.isEmpty()) {
                biggerFromLeft[i] = i;
            } else {
                biggerFromLeft[i] = decreaseOnly.peek();
            }

            decreaseOnly.add(i);
        }

        return biggerFromLeft;
    }
 
    public int[] biggerFromLeft(int[] nums) {
        int[] biggerFromLeft = new int[nums.length];
        Stack<Integer> decreaseOnly = new Stack<>();
        for (int i = 0; i < nums.length; i += 1) {
            while (!decreaseOnly.isEmpty() && nums[decreaseOnly.peek()] <= nums[i]) {
                decreaseOnly.pop();
            }

            if (decreaseOnly.isEmpty()) {
                biggerFromLeft[i] = i;
            } else {
                biggerFromLeft[i] = decreaseOnly.peek();
            }

            decreaseOnly.add(i);
        }

        return biggerFromLeft;
    }
}
 
Sửa lần cuối:
Thế đếch nào bài 3 mình làm có 15 ph mà mình ko làm đc bài 4 nhỉ, éo tính ra time complexity TLE sml =((
 
Bài 3 khoai hơn chứ bài 4 tinh ý xử lý dễ hơn kha khá
Lấy các chuỗi thỏa mãnđộ dài bit nhỏ hơn (ez)
Với các chuỗi bằng độ dài bit, lấy các chuỗi có nửa bit đầu < nửa bit đầu của n
Với chuỗi palindrome có nửa bit đầu = nửa bit đầu của n, check xem có <=n hay k
Ban đầu xử lý ngu đoạn độ dài bit ngang nhau thành cmn căn n
Bài 3 lúc đầu nghĩ hơi phức tạp là tìm next greater element rồi include cả next của next greater element.
Dùng monotonic stack, thấy next greater element thì tính là 1.
Vì nếu b là next greater element của a thì array a và b thỏa mãn, đi thêm 1 pass ngược lại nữa là cover đc cả 2 cases
 

Thống kê chủ đề

Ngày tạo
freedom.9,
Người trả lời cuối
deple20k,
Trả lời
1.686
Lượt xem
107.170
Quay lại
Lên đầu trang