thảo luận Leetcode mỗi ngày

  • Người tạo chủ đề Người tạo chủ đề _Gia_Cat_Luong_
  • Ngày bắt đầu Ngày bắt đầu
Trạng thái
Không mở để trả lời thêm.
Xem tệp đính kèm 2769253
Cuối cùng mình cũng đủ điểm lên Guardian, 1k550 câu trong khoảng 1 năm 6 tháng, rất nhiều lần định bỏ cuộc vì ko giải được những bài easy, medium hay làm ko được bài trong contests. Một hành trình khá dài đối với mình, đặc biệt là khi đã có gia đình, rất mệt nhưng đổi lại rất vui và học được rất nhiều về coding và algorithm, cũng may có Voz lên học hành chém gió :p :p
Tiếp theo là mục tiêu 2k5, để năm sau tính. Chắc để từ 2k1 lên 2k5 sẽ mất khoảng 1 năm nữa.
guâ đần giáng thế, ae 1k4 trong daily triều bái
wryvDSH.png
 
Nếu mục tiêu chỉ để phỏng vấn thì có thể follow theo roadmap của những ng đã từng thành công, trong thớt này cũng có nhiều bạn chia sẻ rồi.
Roadmap mình đề xuất:
1. (1-2 ngày) Big O notation:
2. (14-21 ngày) Cấu trúc dữ liệu căn bản: Học 1 lượt về các cấu trúc dữ liệu căn bản, các thao tác trên CTDL đó và độ phức tạp tương ứng. Hiểu được CTDL nào thì nên dùng lúc nào với bài toán nào. Mục tiêu là làm đc 3-4 bài level super easy cho mỗi CTDL. Có thể sử dụng LC Study Plan cho phần này (https://leetcode.com/study-plan/data-structure/). CTDL căn bản gồm:
  • Mảng
  • Hashtable / Hash Map / Hash Set
  • Stack / queue
  • Linked list
  • Tree các thể loại
  • Graph các thể loại
3. (7 - 14 ngày) Thuật toán căn bản: Học các thuật toán cơ bản thường dùng, và tập phân tích độ phức tạp của mỗi chi phí. Tương tự, mục tiêu là hoàn thành đc 3-4 bài mỗi topic mức độ easy. Bao gồm:
  • Tìm kiếm nhị phân
  • Tìm kiếm tuyến tính
  • Sort: (Quick, merge, heap, count, radix)
  • Prefix sum
  • Đệ quy
  • DFS / BFS

4. (14 - 21 ngày) Đào sâu vào các CTDL nâng cao theo chuyên đề. Vẫn là CTDL nhưng làm các bài medium (5-6 bài mỗi topic) và học thêm các CTDL nâng cao hơn như Trie, Segment Tree,...

5. (21 - 30 ngày) Tương tự nhưng đào sâu vào các thuật toán nâng cao, mỗi topic làm đc 4-5 bài medium. Giai đoạn này mới thực sự là bắt đầu grinding:
  • Sliding window
  • Two pointers
  • Backtracking
  • Monotonic stack / queue
  • Math & Bitwise
  • Geometry
    • Graph algorithms
  • Dynamic programming

6. (7 - 14 ngày) Làm ngẫu nhiên. Qua bước 5 thì thím đã khá vững vàng để chiến đấu rồi, bước tiếp theo là làm ngẫu nhiên các bài level medium (hoặc hard luôn) mà không biết trước chủ đề để tập vận dụng các kiến thức linh hoạt. Mỗi ngày làm 1-3 bài liên tục tầm 1-2 tuần là đc.

7. (Vô chừng) FAANG: Hết bước 6 chỉ cho các bác vào đc cái cty top tier ở VN thôi, để vào FAANG mình nghĩ là cần phải done được các bài hard trong khoản thời gian dưới 45p. Nó khó vkl và mình cũng k chắc là làm được nên k biết chỉ sao.

Cuối cùng, đừng dành hết thời gian vào để cày LC nếu chỉ vì muốn pass phỏng vấn, vì:
  • Phỏng vấn còn rất nhiều phần khác, LC chỉ là cánh cửa đầu tiên. Nếu nói ra nó chiếm đc khoảng 30% kết quả phỏng vấn của các bác thôi.
  • Dù là thuật toán, thì cái code / solution cũng chỉ chiếm được 40% trong cái 30% đó thôi, 60% còn lại là:
    • Cách phát triển vấn đề, tư duy để tìm ra giải pháp
    • Cách code, có gọn gàng sạch đẹp không, có suy nghĩ đc các edge case k, gặp vấn đề cách debug như thế nào
    • Cách trình bày: Phải giải thích được code & ý tưởng của mình cho interviewer hiểu. Nếu không tất cả cũng vô nghĩa
  • Cuối cùng, LC chả giúp gì nhiều trong công việc thực tế, nếu sau khi pass pv xong bạn fail probation thì cũng vậy cả.
p/s: Mình vẫn ở VN, trước mắt cũng k có ý định relocate sang nc ngoài làm việc. Mình làm LC vì sở thích chứ cũng k có mục tiêu vào cty nào.
Xem lại bài cũ thấy roadmap này hợp với beginner như mình, nhưng link free bị outdated rồi:

Khóa học DS (giá bìa 90$): https://leetcode.com/explore/featur...-crash-course-data-structures-and-algorithms/
(đồ miễn phí ngày càng ít nhỉ :D )
 
nãy post nhầm thread, phải đọc 3 hint mới giải được bài hnay, quá ngu mấy bài bit :ah: :ah: :ah:
C#:
public class Solution {
    public long MinEnd(int n, int x)
    {
        var binary = Convert.ToString(x, 2).PadLeft(64, '0').ToCharArray();
        var adding = Convert.ToString(n-1, 2).PadLeft(64, '0');
        var id = adding.Length;
        for (int i = binary.Length - 1; i >= 0; i--)
        {
            if (binary[i] == '1') continue;
            id--;
            binary[i] = adding[id];
        }

        return Convert.ToInt64(string.Join("",binary), 2);
    }
}
 
nãy post nhầm thread, phải đọc 3 hint mới giải được bài hnay, quá ngu mấy bài bit :ah: :ah: :ah:
C#:
public class Solution {
    public long MinEnd(int n, int x)
    {
        var binary = Convert.ToString(x, 2).PadLeft(64, '0').ToCharArray();
        var adding = Convert.ToString(n-1, 2).PadLeft(64, '0');
        var id = adding.Length;
        for (int i = binary.Length - 1; i >= 0; i--)
        {
            if (binary[i] == '1') continue;
            id--;
            binary[i] = adding[id];
        }

        return Convert.ToInt64(string.Join("",binary), 2);
    }
}
1731166810204.png
e còn làm kiểu đếm từng số cho tới khi đủ số thứ n nè
z8SmL8K.png
mà tự dưng lúc làm tới số thứ n nhìn output trông nó quen quen nên suy ra dc cách O(64)
YhCyC2n.png
 
LC 3133 Java linear
Java:
class Solution {
  public static long minEnd(int n, int x) {
    if(x<1<<22)return LongStream.range(1,n).reduce(x,(r,i)->(r+1)|x);else{long r=x;while(n-->1)r=(r+1)|x;return r;}
  }
}
 
Python:
class Solution(object):
    def minEnd(self, n, x):
        """
        :type n: int
        :type x: int
        :rtype: int
        """
        str_n = list((bin(n-1)[2:])[::-1])
        str_x = list((bin(x)[2:])[::-1])
        i = 0
        j = 0
        while j < len(str_n):
            try:
                if str_x[i] == '0':
                    str_x[i] = str_n[j]
                    j += 1
                i += 1
            except Exception:
                str_x.append('0')
        result_str = str_x[::-1]
        return int(''.join(result_str),2)
 
Python:
class Solution:
    def minEnd(self, n: int, x: int) -> int:
        binn = list(bin(n-1)[2:])
        binx = list(bin(x)[2:])
        binn = ['0'] * (64 - len(binn)) + binn
        binx = ['0'] * (64 - len(binx)) + binx
        lx = len(binx)
        count = 0
        for i in range(lx-1,-1,-1):
            if binx[i] == '1':
                binn = binn[:i+1+count] + ['1'] + binn[i+1+count:]
                count += 1
        res = 0
        return int(''.join(binn), 2)
 
Bài daily hôm nay viết thử ra giấy sẽ thấy được pattern :sure: xài python quen rồi ko thèm để ý mấy cái integer limit, giờ đổi qua c++ mất 1 đấm vì không cast qua long long
Đọc đề thì e thấy có 2 nhận xét như thế này:
  • Số đầu tiên luôn luôn là x, vì chắc chắn không có số nào bé hơn x mà AND với tất cả số còn lại ra được x cả
  • Các số còn lại AND x = x -> các vị trí có bit = 1 của x phải được giữ nguyên

-> Fill các bit của (n-1) vào các bit 0 của số x

C++:
class Solution {
public:
    long long minEnd(int n, int x) {
        int significant_bit = 0;
        long long res = x;

        n -= 1;

        for (int i=0; (1<<i) <= x; ++i) {
            if ((1<<i) & x) {
                significant_bit = i;
            } else {
                res |= ((long long)(n & 1) << i);
                n >>= 1;
            }
        }

        res |= ((long long)n << (significant_bit + 1));

        return res;
    }
};
 
Bài daily hôm nay viết thử ra giấy sẽ thấy được pattern :sure: xài python quen rồi ko thèm để ý mấy cái integer limit, giờ đổi qua c++ mất 1 đấm vì không cast qua long long
Đọc đề thì e thấy có 2 nhận xét như thế này:
  • Số đầu tiên luôn luôn là x, vì chắc chắn không có số nào bé hơn x mà AND với tất cả số còn lại ra được x cả
  • Các số còn lại AND x = x -> các vị trí có bit = 1 của x phải được giữ nguyên

-> Fill các bit của (n-1) vào các bit 0 của số x

C++:
class Solution {
public:
    long long minEnd(int n, int x) {
        int significant_bit = 0;
        long long res = x;

        n -= 1;

        for (int i=0; (1<<i) <= x; ++i) {
            if ((1<<i) & x) {
                significant_bit = i;
            } else {
                res |= ((long long)(n & 1) << i);
                n >>= 1;
            }
        }

        res |= ((long long)n << (significant_bit + 1));

        return res;
    }
};
Sao phải chuyển qua c++ thế mai fen

via theNEXTvoz for iPhone
 
Python:
class Solution:
    def minimumSubarrayLength(self, nums: List[int], k: int) -> int:
        bitCount = [0] * 32
        def incBitCount(v):
            for i in range(32):
                if v & (1 << i):
                    bitCount[i] += 1
        def decBitCount(v):
            for i in range(32):
                if v & (1 << i):
                    bitCount[i] -= 1
        def convert():
            value = 0
            for i in range(32):
                value |= (1 if bitCount[i] else 0) << i
            return value
        
        left, result = 0, len(nums) + 1
        for right, num in enumerate(nums):
            incBitCount(num)
            while convert() >= k and left <= right:
                result = min(result, right - left + 1)
                decBitCount(nums[left])
                left += 1
        return result if result != len(nums)+1 else -1
 
LC 3097 Java
Java:
class Solution {
    public int minimumSubarrayLength(int[] nums, int k) {
        int MV = 200002, rs = MV, x = 0;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] >= k) return 1;
            x |= nums[i];
            if (x >= k) {
                int j = i;
                for (int t = nums[i]; t < k; t |= nums[j]) { j--; }
                rs = Math.min(rs, i - j + 1);
                j++;
                x = nums[j];
                i = j;
            }
        }
        return rs < MV ? rs : -1;
    }
}
 
Trạng thái
Không mở để trả lời thêm.

Thống kê chủ đề

Ngày tạo
_Gia_Cat_Luong_,
Người trả lời cuối
Vipluckystar,
Trả lời
17.755
Lượt xem
1.214.491
Quay lại
Lên đầu trang