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

bác nào giải thích cái đề bài giúp e với
Cho xin cái đề với bác, giờ mới biết có group này, zô làm cùng ae cho zui

You are given an array of CPU tasks, each represented by letters A to Z, and a cooling time, n. Each cycle or interval allows the completion of one task. Tasks can be completed in any order, but there's a constraint: identical tasks must be separated by at least n intervals due to cooling time.

Return the minimum number of intervals required to complete all tasks.

Example 1:
Input:
tasks = ["A","A","A","B","B","B"], n = 2
Output: 8
Explanation: A possible sequence is: A -> B -> idle -> A -> B -> idle -> A -> B.
After completing task A, you must wait two cycles before doing A again. The same applies to task B. In the 3rd interval, neither A nor B can be done, so you idle. By the 4th cycle, you can do A again as 2 intervals have passed.
Example 2:

Input:
tasks = ["A","C","A","B","D","B"], n = 1
Output: 6
Explanation: A possible sequence is: A -> B -> C -> D -> A -> B.
With a cooling interval of 1, you can repeat a task after just one other task.
Example 3:

Input:
tasks = ["A","A","A", "B","B","B"], n = 3
Output: 10
Explanation: A possible sequence is: A -> B -> idle -> idle -> A -> B -> idle -> idle -> A -> B.
There are only two types of tasks, A and B, which need to be separated by 3 intervals. This leads to idling twice between repetitions of these tasks.

Tức là nó quăng cho thím 1 mảng các chiêu thức, và thời gian cool down để xài lại chiêu đó lần nữa. Nhiệm vụ của bác là đếm số thời gian để thi triển chiêu ngắn nhất. Trong lúc đợi cooldown thì bác xài chiêu khác, để tiết kiệm thời gian.

Còn giải thích cụ thể thì mình thấy thím này nói rõ nè.

Assuming we have 3A + 3B + 1C with n = 4, the optimal way should be:​

A(4)A(4)AB
Because for the items with lower frequency, we can easily distribute them into the space between A and the rule will be correct.
So if we have 3A, the total length should be
SUM = 3 + (3 - 1)*4 + (2 - 1)

  • 3: The highest frequency
  • (3 - 1)*4: The distance between highest frequency items
  • (2-1): 2 is the count of highest frequency items, minus with 1 because we are already calculated for A
If n is low, it means we can distribute them easily without using an extra character so we should return max(sum, len(tasks))
 
JavaScript:
var leastInterval = function(tasks, n) {
    const g = Object.values(_.groupBy(tasks)).map(it => it.length);
    const m = _.max(g);
    const k = g.filter(it => it === m).length;
    return Math.max((m - 1) * (n + 1) + k, tasks.length);
};
 
Python:
class Solution:
    def leastInterval(self, tasks: List[str], n: int) -> int:
        counts = [0 for i in range(26)]
        maxCount = 0
        for task in tasks:
            idx = ord(task) - ord('A')
            counts[idx] +=1
            if counts[idx] > maxCount:
                maxCount = counts[idx]
        countMax = 0
        for count in counts:
            if count == maxCount:
                countMax +=1
        manyIdleCase = (maxCount - 1)*(n + 1) + countMax
        return max(manyIdleCase, len(tasks))
 
C++:
class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        unordered_map<char, int> mMapCount;
        auto re = tasks.size();
        auto maxFre = 0;
        auto countMaxFre = 1;
        for(auto &c: tasks)
        {
            mMapCount[c]++;
            if(maxFre < mMapCount[c])
            {
                maxFre = mMapCount[c];
                countMaxFre = 1;
            }
            else if (maxFre == mMapCount[c])
            {
                countMaxFre++;
            }
        }
        auto tmp = (n+1) * (maxFre-1)+ countMaxFre;
        if(re < tmp)
        {
            re = tmp;
        }
        return re;
    }
};

Bài nay mình nghĩ ntn
Có 2 khả năng
1 - Ko có idle nào => chính là ví dụ 2 => trả về size của task
2- Có idle => chính là ví dụ 1 => tức là cái task mà count ít không đủ bù đắp cho task có nhiều lần nhất
-> phải đếm count của thằng nhiều lần nhất
-> đến lần cuối cùng sẽ ko cần idle nữa mà dọn dẹp những thằng còn sót lại là xong
-> những thằng còn sót lại chính là những thằng có count = thằng phải làm nhiều lần nhất -> đếm thêm count -> sẽ ra công thức (n+1) * (maxFre-1)+ countMaxFre
 
Java:
class Solution {
    public int leastInterval(char[] tasks, int n) {
        int[] hashtable = new int[26];
        int maxFreq = 0;
        int numOfMaxFreq = 0;

        for (char task: tasks) {
            int i = task - 'A';
            hashtable[i]++;
            if (hashtable[i] > maxFreq) {
                maxFreq = hashtable[i];
                numOfMaxFreq = 1;
            } else if (hashtable[i] == maxFreq) {
                numOfMaxFreq++;
            }
        }

        return Math.max((n + 1) * (maxFreq - 1) + numOfMaxFreq, tasks.length);
    }
}
 
JavaScript:
function leastInterval(tasks: string[], n: number): number {
    let mostFrequency: number = 0;
    let numberOfMostFrequency: number = 0;
    let countMap = {};
    for (let task of tasks) {
        if (!countMap[task]) {
            countMap[task] = 1;
        } else {
            countMap[task]++
        }

        if (mostFrequency === countMap[task]) {
            numberOfMostFrequency++;
        } else if (mostFrequency < countMap[task]) {
            mostFrequency = countMap[task];
            numberOfMostFrequency = 1
        }
    }

    const partCount = mostFrequency - 1;
    const emptySlots = partCount * (n - numberOfMostFrequency + 1);
    const availableSlots = tasks.length - numberOfMostFrequency * mostFrequency;
    const idles = Math.max(0, emptySlots - availableSlots);

    return tasks.length + idles;
};
 
Mới đọc đề tưởng dễ ăn round-robin là xong, submit phát mới nhận ra sai cmnr. Chắc phải ưu tiên lấy từ cái cần chạy nhiều tới cái cần chạy ít, mà mệt quá thức không nổi nữa rồi, chôm bài giữ streak vậy :too_sad:
 
Code:
class Solution:
    def leastInterval(self, tasks: List[str], n: int) -> int:
        count = [0] * 26
        for task in tasks:
            count[ord(task) - ord('A')] +=1
       
        count.sort()
        mx = count[-1] - 1
        slots = mx * n

        for i in range(24, -1, -1):
            slots -= min(mx, count[i])
       
        if slots < 0:
            slots = 0
        return len(tasks) + slots
 
Last edited:
Qua thì medium hard, nay thì medium easy
Code:
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeInBetween(self, list1: ListNode, a: int, b: int, list2: ListNode) -> ListNode:
        head = list1

        for _ in range(a-1):
            head = head.next
        
        tail = head.next
        for _ in range(b-a+1):
            tail = tail.next
        head.next = list2
        while list2.next:
            list2 = list2.next
        list2.next = tail
        return list1
 
Qua thì medium hard, nay thì medium easy
Code:
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeInBetween(self, list1: ListNode, a: int, b: int, list2: ListNode) -> ListNode:
        head = list1

        for _ in range(a-1):
            head = head.next
       
        tail = head.next
        for _ in range(b-a+1):
            tail = tail.next
        head.next = list2
        while list2.next:
            list2 = list2.next
        list2.next = tail
        return list1
Công nhận, đọc đề xong cứ tưởng lừa ở đâu hoặc có cách gì cao siêu
zhtgdqQ.gif
 
C++:
class Solution {
public:
    ListNode* mergeInBetween(ListNode* list1, int a, int b, ListNode* list2) {
        ListNode* dmp = new ListNode(0);
        dmp->next = list1;
        ListNode* tmp = list1;
        for(auto i=0;i<a-1;++i)
        {
            tmp = tmp->next;
        }
        ListNode* tailP = tmp->next;
        for(auto i=0;i<b-a+1;++i)
        {
            tailP = tailP->next;
        }
        tmp->next = list2;
        while(list2->next)
        {
            list2 = list2->next;
        }
        list2->next = tailP;
        return dmp->next;
    }
};
 
code hơi rác, nhưng ko thay đổi tính chất vụ án :look_down:
JavaScript:
function mergeInBetween(list1: ListNode | null, a: number, b: number, list2: ListNode | null): ListNode | null {
    let count = 0;
    let temp = list1, first = null, second = null;
    while (temp && temp.next) {
        if (count === a - 1) {
            first = temp.next;
            temp.next = null;
            break;
        }
        temp = temp.next;
        count++;
    }
    while(first && first.next) {
        if (count === b - 1) {
            second = first.next;
            temp.next = list2;
            while(temp && temp.next) {
                temp = temp.next;
            }
            temp.next = second;
            break;
        }
        first = first.next;
        count++;
    }
    return list1;
};
 
Xưa không biết trò tạo thêm dummy node thì thấy bài này medium thật :)

C#:
public class Solution
{
    public ListNode MergeInBetween(ListNode list1, int a, int b, ListNode list2)
    {
        ListNode dummy  = new ListNode(0, list1);
        ListNode result = dummy;
        ListNode from = null;
        ListNode to = null;

        int index = 0;
        while (dummy != null && (from == null || to == null))
        {
            if (index == a)
            {
                from = dummy;
            }
            if (index == b + 1)
            {
                to = dummy;
            }

            dummy = dummy.next;
            index++;
        }
        from.next = list2;

        while (list2.next != null)
        {
            list2 = list2.next;
        }
        list2.next = to.next;

        return result.next;
    }
}
 
Java:
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeInBetween(ListNode list1, int a, int b, ListNode list2) {
        ListNode dummy = new ListNode(0);
        dummy.next = list1;
        ListNode cur1 = dummy;
        int count = -1;
        ListNode cur2 = list2;
        while (cur2.next != null) {
            cur2 = cur2.next;
        }
        while (cur1.next != null) {
            if (count == b) {
                cur2.next = cur1.next;
                count = 0;
                cur1 = dummy;
                break;
            }
            cur1 = cur1.next;
            count++;
        }
        while (cur1.next != null) {
            if (count == a) {
                cur1.next = list2;
                break;
            }
            cur1 = cur1.next;
            count++;
        }
        return dummy.next;
    }
}
 
Xưa không biết trò tạo thêm dummy node thì thấy bài này medium thật :)

C#:
public class Solution
{
    public ListNode MergeInBetween(ListNode list1, int a, int b, ListNode list2)
    {
        ListNode dummy  = new ListNode(0, list1);
        ListNode result = dummy;
        ListNode from = null;
        ListNode to = null;

        int index = 0;
        while (dummy != null && (from == null || to == null))
        {
            if (index == a)
            {
                from = dummy;
            }
            if (index == b + 1)
            {
                to = dummy;
            }

            dummy = dummy.next;
            index++;
        }
        from.next = list2;

        while (list2.next != null)
        {
            list2 = list2.next;
        }
        list2.next = to.next;

        return result.next;
    }
}
Bài này có insert vào head đâu mà cần dummy node, :ah:
 
Xưa không biết trò tạo thêm dummy node thì thấy bài này medium thật :)

C#:
public class Solution
{
    public ListNode MergeInBetween(ListNode list1, int a, int b, ListNode list2)
    {
        ListNode dummy  = new ListNode(0, list1);
        ListNode result = dummy;
        ListNode from = null;
        ListNode to = null;

        int index = 0;
        while (dummy != null && (from == null || to == null))
        {
            if (index == a)
            {
                from = dummy;
            }
            if (index == b + 1)
            {
                to = dummy;
            }

            dummy = dummy.next;
            index++;
        }
        from.next = list2;

        while (list2.next != null)
        {
            list2 = list2.next;
        }
        list2.next = to.next;

        return result.next;
    }
}
Đúng bài ko cần dummy thì lại thêm dummy, này là học vẹt rồi :sure:
 
Python:
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeInBetween(self, list1: ListNode, a: int, b: int, list2: ListNode) -> ListNode:
        dummy = ListNode(next = list1)
        cnt = 0
        cur = list1
        start , end = None , None
        while cur:
            if cnt == a - 1:start = cur
            if cnt == b + 1: end = cur
            cnt += 1
            cur = cur.next
      
        cur = list2
        start.next = cur
        while cur.next:
            cur = cur.next
        cur.next = end

        return dummy.next
 
Back
Top