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.
dạo ni làm bài ẩu quá, toàn feeling với pass là dc + với bọn lc ra feature tính hộ time complexity cảm giác chệch hướng mục đích làm leetcode, edge case toàn chờ submit xem có bọ ko mới sửa. từ mai điểm danh sẽ tính toán kỹ phần Tc, Sc.
bác lào đăng bài làm thì title nhớ kèm Tc, Sc nữa nhé
JCPvNpV.png
 
JavaScript:
function longestDiverseString(a: number, b: number, c: number): string {
    let result = ''
    const arr = [];
    arr.push(
        { val: a, label: 'a' },
        { val: b, label: 'b' },
        { val: c, label: 'c' }
    )
    const getQuatity = (numb: number) => {
        return numb > 1 ? 2 : 1
    }
    arr.sort((a, b) => b.val - a.val)
    let prev = ''
    while (true) {
        let curMax = arr[0];
        let quatity = 0;
        if (prev == curMax.label) {
            curMax = arr[1];
            quatity = 1
        };
        if (curMax.val < 1) break;
        quatity = quatity ? quatity : getQuatity(curMax.val)
        result += curMax.label.repeat(quatity);
        curMax.val -= quatity
        prev = curMax.label;
        arr.sort((a, b) => b.val - a.val)
    }
    return result;
};
 
dạo ni làm bài ẩu quá, toàn feeling với pass là dc + với bọn lc ra feature tính hộ time complexity cảm giác chệch hướng mục đích làm leetcode, edge case toàn chờ submit xem có bọ ko mới sửa. từ mai điểm danh sẽ tính toán kỹ phần Tc, Sc.
bác lào đăng bài làm thì title nhớ kèm Tc, Sc nữa nhé
JCPvNpV.png
Phải có tính năng tắt cái hiện testcase bị sai đi, chứ làm leetcode nhiều làm mình lười suy nghĩ edge case trước khi code, hư hết cả người, :ah:
 
Thường sẽ nháp ra rồi đặt câu hỏi, ví dụ có 4A 1B thì phải đặt A trước vì nếu đặt B trước sẽ ko đủ kí tự để cắt cái A ra thành 1 valid string, có cái này rồi code greedily luôn 10ph là xong 1 bài :ah:
Mà greedy thường là phần khó nhất trong leetcode cmnr nên fence làm ko ra thì cũng bt thôi :sweat:
Còn backtrack thì fence chỉ nên nghĩ tới khi đề nó cho cái constrain nào n<15 thôi
via theNEXTvoz for iPhone
Bạn có thể chia sẻ cách nhìn ra thuật toán tham lam khi gặp một bài toán bất kỳ được không ?
 
C#:
public class Solution
{
    public string LongestDiverseString(int a, int b, int c)
    {
        int[] remains = new int[] {a, b, c};

        StringBuilder result = new();
        while (true)
        {
            int exclude = -1;
            if (2 <= result.Length)
            {
                if (result[^1] == result[^2])
                {
                    exclude = result[^1] - 'a';
                }
            }
            int letter = GetLetter(remains, exclude);
            if (letter == -1)
            {
                break;
            }
            result.Append((char)(letter + 'a'));
        }

        return result.ToString();
    }

    private int GetLetter(int[] remains, int exclude)
    {
        int candidate = 0;
        int max = 0;
        for (int i = 0; i < remains.Length; i++)
        {
            if (i == exclude)
            {
                continue;
            }
            int remain = remains[i];
            if (max < remain)
            {
                candidate = i;
                max = remain;
            }
        }
        if (max == 0)
        {
            return -1;
        }
        remains[candidate]--;
        return candidate;
    }
}
 
Mình hỏi nghiêm túc không đùa.
Vấn đề với greedy là nhiều lúc mình cũng ko hiểu sao nó đúng và cũng ko chứng minh được là nó đúng hoặc cần rất nhiều thời gian để chứng minh, nhưng mà nó vẫn cho ra kết quả chính xác.
Cũng như có nhiều bài toán thiên niên kỷ đưa ra một mệnh đề và nó đúng với mọi sample nhưng ko ai chứng minh được, bữa bên F17 cũng có 1 bài. Mình nghĩ để giải đc greedy chắc cần kinh nghiệm với observations là chính chứ đi chứng minh nó đúng mới đi giải thì nhiều bài khó lắm.
via theNEXTvoz for iPhone
 
Python:
class Solution:
    def maximumSwap(self, num: int) -> int:
        ans = num
        num = str(num)
        n = len(num)
        digits = [num[i] for i in range(n)]
        for i in range(n):
            for j in range(i + 1, n):
                if digits[i] < digits[j]:
                    digits[i], digits[j] = digits[j], digits[i]
                    ans = max(ans, int(''.join(digits)))
                    digits[i], digits[j] = digits[j], digits[i]

        return ans
Python:
class Solution:
    def maximumSwap(self, num: int) -> int:
        ans = num
        def toDigitArr(num):
            base = 10
            arr = []
            while num > 0:
                arr.append(num%10)
                num//=10
                base*=10
           
            return arr[::-1]
       
        def toInt(arr):
            ans = 0
            n = len(arr)
            for i in range(n):
                ans = ans*10 + arr[i]

            return ans
     
        digits = toDigitArr(num)
        n = len(digits)
        for i in range(n):
            for j in range( i + 1, n):
                if digits[i] < digits[j]:
                    digits[i], digits[j] = digits[j], digits[i]
                    ans = max(ans, toInt(digits))
                    digits[i], digits[j] = digits[j], digits[i]

        return ans
Python:
class Solution:
    def maximumSwap(self, num: int) -> int:
        digits = list(str(num))
        n = len(digits)
        rightMax = [-1]*n
        rightMax[n - 1] = n - 1
        for i in range(n - 2, -1, -1):
            rightMax[i] = rightMax[i + 1] if digits[i] <= digits[rightMax[i + 1]] else i

        for i in range(n):
            if digits[i] < digits[rightMax[i]]:
                digits[i], digits[rightMax[i]] = digits[rightMax[i]], digits[i]
                return int(''.join(digits))

        return num
 
Sửa lần cuối:
C++:
class Solution {
public:
    int maximumSwap(int num) {
        priority_queue<int> pq;
        vector<int> tmp;

        while (num > 0) {
            int temp = num % 10;
            pq.push(temp);
            tmp.push_back(temp);
            num /= 10;
        }

        int n = pq.size();

        for (int i = 0; i < n/2; i++) {
            int temp = tmp[i];
            tmp[i] = tmp[n - i - 1];
            tmp[n - i - 1] = temp;
        }

        for (int i = 0; i < n; i++) {
            if (tmp[i] != pq.top()) {
                for (int j = n - 1; j > i; j--) {
                    if (tmp[j] == pq.top()) {
                        int x = tmp[i];
                        tmp[i] = tmp[j];
                        tmp[j] = x;
                        break;
                    }
                }
                break;
            }
            else if (tmp[i] == pq.top()) {
                pq.pop();
            }
        }

        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans += tmp[i];
            if (i != n - 1) {
                ans *= 10;
            }
        }
       
        return ans;
    }
};
 
C++:
class Solution {
public:
    int maximumSwap(int num) {
        string s = to_string(num);
        vector<char> max_num(s.size()+1);
        max_num[s.size()] = s.size()-1;

        for (int i = s.size() - 1; i >= 0; i--) {
            max_num[i] = i;
            if (s[i] <= s[max_num[i+1]]) {
                max_num[i] = max_num[i+1];
            }
        }

        for (int i = 0; i < s.size() - 1; i++) {
            if (s[i] < s[max_num[i+1]]) {
                swap(s[i], s[max_num[i+1]]);
                break;
            }
        }
        
        return stoi(s);
    }
};
1729129025291.png
 
Thấy cũng ko khó lắm :doubt:
JavaScript:
function maximumSwap(num: number): number {
    const digits: number[] = num.toString().split('').map(Number);
    const idxes: number[] = new Array(10).fill(-1);

    for (let i = 0; i < digits.length; i++) {
        idxes[digits[i]] = i;
    }

    for (let i = 0; i < digits.length; i++) {
        for (let j = 9; j > digits[i]; j--) {
            if (idxes[j] > i) {
                [digits[i], digits[idxes[j]]] = [digits[idxes[j]], digits[i]];
                return parseInt(digits.join(''));
            }
        }
    }
    return num;
}
 
Bạn có thể chia sẻ cách nhìn ra thuật toán tham lam khi gặp một bài toán bất kỳ được không ?
Ngày xưa mình từng đọc ở đâu đó(hình như là vnoi), 1 hiền nhân đã tổng quát về tham lam bằng vài ý: :beauty:
  • Dễ nghĩ, dễ cài, chạy nhanh, nhưng chưa chắc đã đúng
  • Tính đúng đắn: Không chứng minh được cách tham lam là đúng thì đừng làm, mắc công sau thằng khác hỏi...
  • Nếu thực thi DP, Bạch Trạch như đi ô tô xe máy trên cao tốc thì thực thi tham lam không khác gì lính đang đi trên bãi mìn vì 1 bài có thể thực thi bằng rất nhiều cách tham lam, nhưng thường chỉ có 1 cách đúng thôi...
  • Tham lam không có cách thực thi tổng quát nào cả, mỗi bài 1 kiểu, làm nhiều thì khôn
  • 1 số dấu hiệu có thể là của bài toán tham lam:
  • Đề bài dài vl, trông có vẻ cực kì khó,
  • Đề bài dữ liệu cực kì lớn, lớn đến nỗi mà O(n^2) cũng fail, bỏ qua được mấy cách DP, Bạch Trạch đi
  • Khó quá đéo làm đc...:amazed:
 
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.213.926
Quay lại
Lên đầu trang