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.
Bài hôm nay đọc vào là nghĩ ngay đến greedy rồi, nhưng lại bị chệch hướng. Ban đầu tư duy đơn giản: - Với một vị trí start t và lượng nhiên liệu f, mình sẽ đi được tối đa đến vị trí t + f
  • Vậy nếu đổ xăng, mình sẽ đổ tại station nào đó trong khoảng từ t -> t + f mà có lượng xăng lớn nhất
  • Vị trí đổ không quan trọng vì lượng xăng còn tồn vẫn được giữ lại
=> Bị lỗi trường hợp đôi khi mình cần đổ 2 3 station (hoặc hơn nữa) mới đến được vị trí tiếp theo

  • Vậy nếu không đến được vị trí tiếp theo thì sẽ đổ thêm tại các trạm khác
  • Mà nếu đã đổ thì cứ lựa trạm lớn nhất có thể mà đổ
=> Dùng heap
Mình sai cái trường hợp đầu tận 4 lần :beat_brick: cứ nghĩ mình đúng cho tới khi gặp cái test case lỗi (3 lần đầu là code ngu dính edge case nên chưa phát hiện, lần 4 mới phát hiện là lỗi logic)
Cách làm thì cũng dùng heap như fen
1660991921093.png
 
C

Công ty nào mà 1 line code bị xuống làm tester vậy thím. Nói để anh em né :(
Ngoại trừ BoschRBVH VN còn làm chiêu đó cho fresher thôi chớ.
Có người kể cho em thế mà em cũng không dám hỏi thêm bác ạ.
at9JAlm.gif
.
Còn bài hôm nay em đọc thấy cái constraint số trạm xăng chỉ có 500 là O(n^2) duyệt hết làm 1 quả dp. Java được có 10% time mà cứ thấy pass là bỏ đi chơi gem
NMwYNcc.gif
.
 
Mình đang có một bài toán liên quan tới task scheduling. Đại loại là có 1 tập các task cần thực thi, mỗi task bao gồm thời gian hoàn thành và một bộ các task cần phải hoàn thành trước khi bắt đầu. Và có một số lượng workers độc lập.
Câu hỏi là phân chia task như thế nào để:
1. Task không được thực thi trước khi tất cả các required task hoàn thành.
2. Không để xảy ra trường hợp idling workers và available tasks. (đại loại là task có thể start now nhưng không assign cho worker).

Các bác có cao kiến gì giúp với
 
Bài hôm nay đúng là trò lừa, thêm cái điều kiện target.lengh() * 10 nhìn cũng sợ nhưng thực ra chả bao giờ cần đến quá target.length() lần đóng dấu.

Ý tưởng:
  • Truy ngược từ target về đầu,
  • Ở mỗi bước, tìm trong chuỗi target một substring match* được cái stamp. Replace hết tất cả các ký tự trong đó thành '?',
*match: match ở đây có nghĩa là ký tự trong target là '?' hoặc bằng ký tự trong stamp. Nhưng yêu cầu phải có ít nhất một ký tự không phải '?',
  • Nếu không tìm thấy substring nào tức là không có cách giải, trả về vector rỗng,
  • Nếu toàn bộ chuỗi target bị replace thành _ thì dừng lại.


Lúc đầu thấy cái target * 10 tưởng là sẽ có case hiểm nào khác nên submit bừa theo ý tưởng trên để xem sai chỗ nào, không ngờ làm phát ăn luôn.
https://leetcode.com/submissions/detail/779163302/

Mình đang có một bài toán liên quan tới task scheduling. Đại loại là có 1 tập các task cần thực thi, mỗi task bao gồm thời gian hoàn thành và một bộ các task cần phải hoàn thành trước khi bắt đầu. Và có một số lượng workers độc lập.
Câu hỏi là phân chia task như thế nào để:
1. Task không được thực thi trước khi tất cả các required task hoàn thành.
2. Không để xảy ra trường hợp idling workers và available tasks. (đại loại là task có thể start now nhưng không assign cho worker).

Các bác có cao kiến gì giúp với

Có cần tối ưu gì không? VD như cần thời gian hoàn thành tất cả task là nhỏ nhất.
Nếu không thì cứ greedy mà làm thôi. Tạo danh sách task available, có bao nhiêu worker thì phân hết vào, hoàn thành thì update danh sách.
 
Sửa lần cuối:
Có cần tối ưu gì không? VD như cần thời gian hoàn thành tất cả task là nhỏ nhất.
Nếu không thì cứ greedy mà làm thôi. Tạo danh sách task available, có bao nhiêu worker thì phân hết vào, hoàn thành thì update danh sách.
Mình nghĩ cần phải tìm cách nào đó tối ưu thứ tự ưu tiên của task ấy. VD có 3 task (A,B,C) không phụ thuộc, task D depends on B và C, 2 workers, thì mình assign cho B và C chạy trước, đại loại vậy.
 
Mình đang có một bài toán liên quan tới task scheduling. Đại loại là có 1 tập các task cần thực thi, mỗi task bao gồm thời gian hoàn thành và một bộ các task cần phải hoàn thành trước khi bắt đầu. Và có một số lượng workers độc lập.
Câu hỏi là phân chia task như thế nào để:
1. Task không được thực thi trước khi tất cả các required task hoàn thành.
2. Không để xảy ra trường hợp idling workers và available tasks. (đại loại là task có thể start now nhưng không assign cho worker).

Các bác có cao kiến gì giúp với
Các task phụ thuộc vào nhau thì build thành DAG, sau đó dùng topology sorting để sort thì sẽ ra thứ tự thực thi. Tuy nhiên nên tìm hiểu rồi dùng airflow nhé. Tự build thì bao giờ mới xong.
 
Mình nghĩ cần phải tìm cách nào đó tối ưu thứ tự ưu tiên của task ấy. VD có 3 task (A,B,C) không phụ thuộc, task D depends on B và C, 2 workers, thì mình assign cho B và C chạy trước, đại loại vậy.
Đọc về topological sort đi thím https://www.interviewcake.com/concept/java/topological-sort
Problem của bác giống mấy bài parallel courses ở trên leetcode nhưng mà có yếu tố thời gian vs cả số lượng k worker cố định nên e thử propose 1 cách làm topological sort+ greedy 1 chút nhé.
  • Đầu tiên là build 1 cái DAG dựa vào các dependencies kia. Xong r xác định các node(từ giờ coi node = task) có indegree=0. Giả sử L là list các node có indegree=0
  • Schedule các node trong L vào k workers theo ưu tiên node nào có tg hoàn thành sớm hơn thì schedule trước.
  • Mỗi khi có 1 task được hoàn thành thì update lại indegree của các task phụ thuộc vào nó. Nếu thấy đc node nào có indegree =0 thì add node đó vào L
  • Cứ có worker nào rảnh (vd worker vừa thực hiện task xong, hoặc schedule ở b2 xong còn thừa worker rảnh) thì cho worker đó thực hiện task có tg hoàn thành ngắn nhất trong L ( Dùng heap pop để lấy phần tử nhỏ nhất cho nhanh)
Nếu thím chưa biết về topological sort hay heap thì đọc để hiểu mấy khái niệm cơ bản như là DAG, indegree, heap,... nhé. Trong này toàn tay to leetcode nên mấy cái khái niệm trên mấy bác ý dùng như cơm bữa thôi :D
 
Lúc đầu thấy cái target * 10 tưởng là sẽ có case hiểm nào khác nên submit bừa theo ý tưởng trên để xem sai chỗ nào, không ngờ làm phát ăn luôn.
nghĩ ra case bí hiểm đi hình như submit test case được 100 coin = x10 số lượng coin AC đóa
cgE9MkI.gif
 
nay bài dễ, tiếp tục 1 line, :p
Python:
return True if n == 1 else False if n%4 != 0 or n <= 0 else self.isPowerOfFour(n//4)

Python:
return any(x for x in [1,4,16,64,256,1024,4096,16384,65536,262144,1048576,4194304,16777216,67108864,268435456,1073741824] if x == n)
 
Sửa lần cuối:
Bài hôm nay làm nhớ tới 4 nam trc pvan o cty outsource (Yêu cầu là không được dùng các hàm hỗ trợ) :p
Mã:
if(n == 0) {
    return false
}
  while(n > 1)
  {   
   if(n % 4 != 0) {
      return false
   }
    n = n / 4;     
  }
  return true
 
Đây mới đích thực là one-liner:


Python:
return n in [0x1, 0x4, 0x10, 0x40, 0x100, 0x400, 0x1000, 0x4000, 0x10000, 0x40000, 0x100000, 0x400000, 0x1000000, 0x4000000, 0x10000000, 0x40000000]
 
Cách giải không cần loop, không cần hàm hỗ trợ (__builtin_clz là một instruction có sẵn, gọi trực tiếp assembly thay vào cũng được). Test n in array bản chất vẫn là loop rồi.

C++:
    bool isPowerOfFour(int n) {
        auto lg2 = n > 0 ? sizeof(n)*8 - 1 - __builtin_clz(n) : -1;
        return n > 0 && (lg2 % 2 == 0) && ((1LL << lg2) == n);
    }

Cách khác:

C++:
    bool isPowerOfFour(int n) {
        return n > 0 && (n & (n-1) == 0) && (n & 0x55555555));
    }
Giải thích: để là lũy thừa của 4 thì cần:
  • Lớn hơn 0
  • Là lũy thừa của 2. Tức biểu diễn nhị phân có dạng 1000...000. Khi đó n & (n-1) == 10...000 & 01...111 = 0
  • Bit 1 phải nằm ở vị trí lẻ. Số 0x55555555 có biểu diễn nhị phân là 010101...01, khi and với n sẽ trả về khác 0 nếu trong n có 1 bit ở vị trí lẻ.
 
Sửa lần cuối:
Python:
return n in (1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824)
 
Java:
 public boolean isPowerOfFour(int n) {
        
        if (n <= 0) return false;
        while (n  > 1){
            if (n % 4 != 0) return false;
            else {
                n = n/4;
            }
        }
        return true;
    }
 
Giải thích: để là lũy thừa của 4 thì cần:
  • Lớn hơn 0
  • Là lũy thừa của 2. Tức biểu diễn nhị phân có dạng 1000...000. Khi đó n & (n-1) == 10...000 & 01...111 = 0
  • Bit 1 phải nằm ở vị trí lẻ. Số 0x55555555 có biểu diễn nhị phân là 010101...01, khi and với n sẽ trả về khác 0 nếu trong n có 1 bit ở vị trí lẻ.
não to thặc, đáng lẽ nên để đọc giả tự tìm hiểu
dciObBx.gif
 
Giải thích: để là lũy thừa của 4 thì cần:
  • Lớn hơn 0
  • Là lũy thừa của 2. Tức biểu diễn nhị phân có dạng 1000...000. Khi đó n & (n-1) == 10...000 & 01...111 = 0
  • Bit 1 phải nằm ở vị trí lẻ. Số 0x55555555 có biểu diễn nhị phân là 010101...01, khi and với n sẽ trả về khác 0 nếu trong n có 1 bit ở vị trí lẻ.
não to thặc, đáng lẽ nên để đọc giả tự tìm hiểu
dciObBx.gif
K có đoạn giải thích này thì sao mà hiểu được, :beat_shot:
 
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.212.708
Quay lại
Lên đầu trang