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
e giải toàn kiểu ngồi ngâm, observe data 1 lúc lâu mới giải, làm kiểu đó vào là thấy cho rớt từ vòng gửi xe r :sad:nghe mấy lò luyện pvan trên mạng toàn kêu chấm cảđiểm giao tiếp. điểm trình bày suy nghĩ nữa
Chắc do vibe coding nhiều quá hư não rồi đó fen
g8XXj8u.gif


via theNEXTvoz for iPhone
 
móc mỉa gì đâu, mấy cty tier 1/faang thì pv mid level hỏi dsa là chính mà, mà đa số là medium thôi, chừng nào senior thì mới đòi hỏi cao về system design. Trong này quất hard ầm ầm làm mình thắc mắc là mấy thím có đi pv ko?
T chưa phỏng vấn faang nhưng pv tier 1 ở VN thì làm 2 câu hard còn oa là medium rồi nhé thím
Với làm contest làm vui vui là chính thôi
 
nói chung là phỏng vấn cũng vô vàn, tôi chơi với 1 thằng cũng tryhard thi icpc (tạch ở vòng chọn đội), tầm 2k cf gì đấy thì đi phỏng vấn k ăn dc bài calculator nhé, bị dí dí tí lăn đùng ra ngay
 
ngâm mãi vẫn chưa hiểu Q3 của weekly contest tuần trước =((
Cái q3 nó là thế này, zigzag nghĩa là 3 phần tử liên tiếp nó form cái shape như này \/ hoặc là /\.
Nếu dpUp[index][val] là số cách chọn ở index i với val mà index tiếp theo là up, thì số cách chọn dpUp[index][val] sẽ là tổng của dpDown[i-1][preVal] ở đây preVal phải > val hiện tại mình muốn chọn. Để có thể form đc cái shape như này \/.
Tương tự với dpDown[index][val] nó sẽ form đc cái shape Zigzag như này
/\, số cách chọn dpDown[index][val] sẽ là tổng của dpUp[i-1][preVal] ở đây preVal phải < val
Python:
class Solution:
    def zigZagArrays(self, n: int, l: int, r: int) -> int:
        MOD = 10**9 + 7
        up = [0] * (r + 2)
        down = [0] * (r + 2)
        for j in range(l, r + 1):
            up[j] = 1
            down[j] = 1

        prefixUp = [0] * (r + 2)
        postfixDown = [0] * (r + 2)

        s = 0
        for j in range(l, r + 1):
            s += up[j]
            prefixUp[j] = s % MOD
        s = 0
        for j in range(r, l - 1, -1):
            s += down[j]
            postfixDown[j] = s % MOD

        for _ in range(1, n):
            cUp = [0] * (r + 2)
            cDown = [0] * (r + 2)
            for j in range(l, r + 1):
                cUp[j] = postfixDown[j + 1]
                cDown[j] = prefixUp[j - 1]

            up, down = cUp, cDown

            s = 0
            for j in range(l, r + 1):
                s += up[j]
                prefixUp[j] = s % MOD
              
            s = 0
            for j in range(r, l - 1, -1):
                s += down[j]
                postfixDown[j] = s % MOD

        return (sum(up[l:r + 1]) + sum(down[l:r + 1])) % MOD

Nếu nghĩ theo hướng index là phần tử middle giữa 3 phần tử để form 1 cái zigzag thì implement khá dễ với prefixSum với bottom up, mình đi dp topdown rồi maintain cái biến streak nên ko làm ra do time complexity cao quá.
 
Cái q3 nó là thế này, zigzag nghĩa là 3 phần tử liên tiếp nó form cái shape như này \/ hoặc là /\.
Nếu dpUp[index][val] là số cách chọn ở index i với val mà index tiếp theo là up, thì số cách chọn dpUp[index][val] sẽ là tổng của dpDown[i-1][preVal] ở đây preVal phải > val hiện tại mình muốn chọn. Để có thể form đc cái shape như này \/.
Tương tự với dpDown[index][val] nó sẽ form đc cái shape Zigzag như này
/\, số cách chọn dpDown[index][val] sẽ là tổng của dpUp[i-1][preVal] ở đây preVal phải < val
Python:
class Solution:
    def zigZagArrays(self, n: int, l: int, r: int) -> int:
        MOD = 10**9 + 7
        up = [0] * (r + 2)
        down = [0] * (r + 2)
        for j in range(l, r + 1):
            up[j] = 1
            down[j] = 1

        prefixUp = [0] * (r + 2)
        postfixDown = [0] * (r + 2)

        s = 0
        for j in range(l, r + 1):
            s += up[j]
            prefixUp[j] = s % MOD
        s = 0
        for j in range(r, l - 1, -1):
            s += down[j]
            postfixDown[j] = s % MOD

        for _ in range(1, n):
            cUp = [0] * (r + 2)
            cDown = [0] * (r + 2)
            for j in range(l, r + 1):
                cUp[j] = postfixDown[j + 1]
                cDown[j] = prefixUp[j - 1]

            up, down = cUp, cDown

            s = 0
            for j in range(l, r + 1):
                s += up[j]
                prefixUp[j] = s % MOD
             
            s = 0
            for j in range(r, l - 1, -1):
                s += down[j]
                postfixDown[j] = s % MOD

        return (sum(up[l:r + 1]) + sum(down[l:r + 1])) % MOD

Nếu nghĩ theo hướng index là phần tử middle giữa 3 phần tử để form 1 cái zigzag thì implement khá dễ với prefixSum với bottom up, mình đi dp topdown rồi maintain cái biến streak nên ko làm ra do time complexity cao quá.
quả não tàn của e chỉ làm được top down nhưng TLE =((

Number of ZigZag Arrays I - LeetCode (https://leetcode.com/problems/number-of-zigzag-arrays-i/submissions/1787387402/)
 
TLE là đúng rồi vì nếu đi theo hướng này nó là On^4 mà, phải có cách chuyển về prefixsum để giải còn On^2 thôi.
Có thể giải được bằng On^3 bằng cách dp(i, streak, lastVal) và bên trong thì loop từ last tới right + 1 hoặc left tới last nhưng mà cũng chết =(( vì với cách này ko tận dụng đc prefixSum để giảm về O(n^2)
Cái key point bài này là phải nghĩ cách để bỏ cái biến streak ra, maintain cái streak này thì ko giải được :ah:
 
TLE là đúng rồi vì nếu đi theo hướng này nó là On^4 mà, phải có cách chuyển về prefixsum để giải còn On^2 thôi.
Có thể giải được bằng On^3 bằng cách dp(i, streak, lastVal) và bên trong thì loop từ last tới right + 1 hoặc left tới last nhưng mà cũng chết =(( vì với cách này ko tận dụng đc prefixSum để giảm về O(n^2)
Cái key point bài này là phải nghĩ cách để bỏ cái biến streak ra, maintain cái streak này thì ko giải được :ah:
sao lại O(N^4) được bác? O(N*M) thôi chứ, N = max n, M = max(r - l + 1) vì dfs cũng chỉ là O(1) thôi mà vì cache lại toàn bộ mảng dp thì cao nhất là 2 * 2000 * 2000. Chẳng qua chạy recursion nên nó bị TLE. Em chạy worst case riêng vẫn ổn mà
1759278276050.png
 
sao lại O(N^4) được bác? O(N*M) thôi chứ, N = max n, M = max(r - l + 1) vì dfs cũng chỉ là O(1) thôi mà vì cache lại toàn bộ mảng dp thì cao nhất là 2 * 2000 * 2000. Chẳng qua chạy recursion nên nó bị TLE. Em chạy worst case riêng vẫn ổn mà
Xem tệp đính kèm 3263781
À đúng rồi mình đọc nhầm tưởng bác shrink cái left right qua cái do function do viết &l, &r, &n.
Vậy chỉ là 2*2000*2000 thôi mà sao nó ko pass hết nhỉ
ghXpJrI.gif

Submit lại lần nữa xem có ok ko, c++ là nhanh nhất rồi mà
via theNEXTvoz for iPhone
 
sao lại O(N^4) được bác? O(N*M) thôi chứ, N = max n, M = max(r - l + 1) vì dfs cũng chỉ là O(1) thôi mà vì cache lại toàn bộ mảng dp thì cao nhất là 2 * 2000 * 2000. Chẳng qua chạy recursion nên nó bị TLE. Em chạy worst case riêng vẫn ổn mà
Xem tệp đính kèm 3263781
Mình viết Python thế này cũng TLE dù bottom up đây, phải nhờ chat GPT nó optimize dùng variable thay vì xử lí trên mảng prefixSum trực tiếp mới pass, ảo lắm.
Mấy thằng rank cao nó switch solution khiếp vãi, đầu óc nhảy số nhanh, kiên nhẫn ngồi debug rồi chửi Leetcode :sweat:

 
Sửa lần cuối:
Rank 7xx mà được cộng có 17 điểm =(( Mà cái rank này hơi ảo nhỉ, xưa rank 8 900 tầm rank này là cộng cũng phải 30 điểm
1759360976261.png
Chắc phải 2 cái contests nữa rank 5xx mới lên nổi, thời đại AI khó leo rank quá :ah:
 
1759569852144.png

Mới làm thử virtual weekly tuần trước. Làm được câu 3 nma tạch câu 4. Câu 4 phải nhìn được nó dưới dạng matrix multiplication và đưa về fast exponential để giảm xuống còn log(n) :(
 
Cái q3 nó là thế này, zigzag nghĩa là 3 phần tử liên tiếp nó form cái shape như này \/ hoặc là /\.
Nếu dpUp[index][val] là số cách chọn ở index i với val mà index tiếp theo là up, thì số cách chọn dpUp[index][val] sẽ là tổng của dpDown[i-1][preVal] ở đây preVal phải > val hiện tại mình muốn chọn. Để có thể form đc cái shape như này \/.
Tương tự với dpDown[index][val] nó sẽ form đc cái shape Zigzag như này
/\, số cách chọn dpDown[index][val] sẽ là tổng của dpUp[i-1][preVal] ở đây preVal phải < val
Python:
class Solution:
    def zigZagArrays(self, n: int, l: int, r: int) -> int:
        MOD = 10**9 + 7
        up = [0] * (r + 2)
        down = [0] * (r + 2)
        for j in range(l, r + 1):
            up[j] = 1
            down[j] = 1

        prefixUp = [0] * (r + 2)
        postfixDown = [0] * (r + 2)

        s = 0
        for j in range(l, r + 1):
            s += up[j]
            prefixUp[j] = s % MOD
        s = 0
        for j in range(r, l - 1, -1):
            s += down[j]
            postfixDown[j] = s % MOD

        for _ in range(1, n):
            cUp = [0] * (r + 2)
            cDown = [0] * (r + 2)
            for j in range(l, r + 1):
                cUp[j] = postfixDown[j + 1]
                cDown[j] = prefixUp[j - 1]

            up, down = cUp, cDown

            s = 0
            for j in range(l, r + 1):
                s += up[j]
                prefixUp[j] = s % MOD
             
            s = 0
            for j in range(r, l - 1, -1):
                s += down[j]
                postfixDown[j] = s % MOD

        return (sum(up[l:r + 1]) + sum(down[l:r + 1])) % MOD

Nếu nghĩ theo hướng index là phần tử middle giữa 3 phần tử để form 1 cái zigzag thì implement khá dễ với prefixSum với bottom up, mình đi dp topdown rồi maintain cái biến streak nên ko làm ra do time complexity cao quá.
Cái này bác log ra sẽ thấy top == down[::-1]
Nên câu này chỉ cần 1 array dp thôi là đủ.

Qua Q4 thì phải biểu diễn được cái array dp này dưới dạng phép nhân ma trận

Python:
MOD = 1_000_000_007

class Solution:
    def zigZagArrays(self, n: int, l: int, r: int) -> int:
        m = r - l + 1
        dp = [i for i in range(m)]
        for _ in range(n - 2):
            new_dp = [0]
            curr = dp[m - 1] % MOD
            i = m - 1
            while i > 0:
                new_dp.append(curr % MOD)
                i -= 1
                curr += dp[i]
                curr %= MOD
            dp = new_dp[:]
        return (sum(dp) * 2) % MOD
 
Cái này bác log ra sẽ thấy top == down[::-1]
Nên câu này chỉ cần 1 array dp thôi là đủ.

Qua Q4 thì phải biểu diễn được cái array dp này dưới dạng phép nhân ma trận

Python:
MOD = 1_000_000_007

class Solution:
    def zigZagArrays(self, n: int, l: int, r: int) -> int:
        m = r - l + 1
        dp = [i for i in range(m)]
        for _ in range(n - 2):
            new_dp = [0]
            curr = dp[m - 1] % MOD
            i = m - 1
            while i > 0:
                new_dp.append(curr % MOD)
                i -= 1
                curr += dp[i]
                curr %= MOD
            dp = new_dp[:]
        return (sum(dp) * 2) % MOD
Về cơ bản là markov chain :big_smile:
 

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.188
Quay lại
Lên đầu trang