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.
Java:
class Solution {
    public int minOperations(int[] nums) {
        Map<Integer,Integer> map = new HashMap();
        int ans =0;
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        for(int num:map.values()){
            if(num==1) return -1;
            ans+=findOperations(num);
        
        }
        return ans;
    }
    public int findOperations(int num){
        int ans =0;
        while(num>0){
            if(num-3==0||num-3>=2){
                num=num-3;
                ans++;
            }else{
                num=num-2;
                ans++;
            }
        }
        return ans;
    }
}
 
Thím thao khảo qua, quan trọng là làm nhiều quen cách tư duy :v
Qui hoạch động thì phải kinh thánh này. Cơ mà làm nhiều thì ko ngại mấy bài medium lắm chỉ ngại mấy bài hard DP mix thêm quả bitmasking :beat_brick:
 
Java:
class Solution {
    public int minOperations(int[] nums) {
        Map<Integer,Integer> map = new HashMap();
        int ans =0;
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        for(int num:map.values()){
            if(num==1) return -1;
            ans+=findOperations(num);
      
        }
        return ans;
    }
    public int findOperations(int num){
        int ans =0;
        while(num>0){
            if(num-3==0||num-3>=2){
                num=num-3;
                ans++;
            }else{
                num=num-2;
                ans++;
            }
        }
        return ans;
    }
}
Em cũng có ý tưởng giống bác là count phần tử, nhưng khúc cuối tìm cách tách num = 3x + 2y mà chưa ra :cry:
 
Em cũng có ý tưởng giống bác là count phần tử, nhưng khúc cuối tìm cách tách num = 3x + 2y mà chưa ra :cry:
Nghĩ đơn giản như thế này, nếu có 3 phần tử thì có 1 operation, 4 phần tử thì lấy 1 từ operation ban đầu để xử lí phần thừa nên tách thành 2 operations. 5 phần tử thì ko cần mượn nhưng vẫn cần 1 operation nữa để delete vẫn là 2 operations.
Nên greedy là /3, nhưng remainder là 1 thì cần mượn 1 phần tử từ trước đó, hay là 2 thì ko cần mượn nhưng tóm lại là operations phải cộng thêm 1 cho case này.
Trò mượn này học được từ bác @Violet_7 trong 1 bài contest nào đó :sexy_girl: khá dễ hiểu để áp dụng trong các bài greedy kiểu này

via theNEXTvoz for iPhone
 
Java:
class Solution {
  public int minOperations(int[] nums) {
    int[] count = new int[1000001];
    for (int num: nums) {
      count[num]++;
    }
    int ans = 0;
    for (int num: count) {
      if (num == 0) continue;

      if (num == 1) return -1;
      else if (num % 3 == 0) ans += num / 3;
      else if (num % 3 != 0) ans += num / 3 + 1;
    }
    return ans;
  }
}
 
Em cũng có ý tưởng giống bác là count phần tử, nhưng khúc cuối tìm cách tách num = 3x + 2y mà chưa ra :cry:
Nó chỉ có mấy case là count == 1 thì sure kèo không xóa được hết, count % 3 == 0 thì số operation thấp nhất luôn = count / 3, count % 3 == 1 thì là 1 chuỗi 3 + với 2 số 2 ở cuối, count % 3 == 2 thì là 1 chuỗi 3 với 1 số 2 ở cuối, nghĩ thế cho đơn giản :D
 
Java:
class Solution {
    public int minOperations(int[] nums) {
        Arrays.sort(nums);
        int prev=-1;
        int count=0;
        int res=0;
        for(int i=0;i<nums.length;++i){
            if(prev!=nums[i]){
                if(count==1)return -1;
                else if(count%3!=0)res+=(count/3)+1;
                else res+=count/3;
                count=1;
                prev=nums[i];
            }else count++;
        }
        if(count==1)return -1;
        else if(count%3!=0)res+=(count/3)+1;
        else res+=count/3;
        return res;
    }
}
 
C#:
public int MinOperations(int[] nums)
{
    var dic = new Dictionary<int, int>();
    foreach (var num in nums)
    {
        dic[num] = dic.GetValueOrDefault(num) + 1;
    }

    int max = dic.Max(x => x.Value);
    var dp = new int[max +1];
    Array.Fill(dp, int.MaxValue);
    dp[0] = 0;
    for (int i = 2; i <= 3; i++)
    {
        for(int j = 0; j <= max - i; j++)
        {
            if (dp[j] != int.MaxValue)
            {
                dp[i + j] = Math.Min(dp[j] + 1, dp[i + j]);
            }
        }
    }

    int sum = 0;
    foreach (var pair in dic)
    {
        if (dp[pair.Value] == int.MaxValue)
        {
            return -1;
        }

        sum += dp[pair.Value];
    }

    return sum;
}
 

Tệp đính kèm

  • 20240104_140815.jpg
    20240104_140815.jpg
    224,8 KB · Lượt xem: 56
Thím thao khảo qua, quan trọng là làm nhiều quen cách tư duy :v
Thanks thím nhé, để luyện lại dạng dynamic phát, cuối tháng vừa rồi gặp 2 bài dynamic đứng hình luôn :))
 
Mã:
class Solution:
    def minOperations(self, nums: List[int]) -> int:
        def get(num):
            cnt = 0
            while num > 0:
                if num % 3 == 0:
                    num -= 3
                else:
                    num -= 2
                cnt += 1
            return cnt
        mp = {}
        for num in nums:
            mp[num] = mp.get(num , 0) + 1
        res = 0
        for k in mp:
            if mp[k] == 1:
                return -1
            res += get(mp[k])
        return res
ZJqL4rW.png
 
JavaScript:
function minOperations(nums: number[]): number {
    const intergerFrequency = new Map<number, number>();

    for (const num of nums){
        intergerFrequency.set(num, (intergerFrequency.get(num) || 0)+1);
    }

    let operationNumber = 0;
    for (const [num, frequency] of intergerFrequency){
        if (frequency === 1){
            return -1;
        }
        operationNumber += Math.ceil(frequency/3)
    }
    return operationNumber;
};
Mã:
defmodule Solution do
  @spec min_operations(nums :: [integer]) :: integer
  def min_operations(nums) do
    integer_frequency = Enum.reduce(nums, %{}, fn num, acc ->
        Map.update(acc, num, 1, &(&1 + 1))
    end)

    Enum.reduce_while(integer_frequency, 0, fn {_integer, frequency}, acc ->
        if (frequency == 1) do
            {:halt, -1}
        else
            {:cont, acc + Float.ceil(frequency/3)}
        end
    end)
    |> trunc()
  end
end
 
01/04/2024:
Python:
class Solution:
    def minOperations(self, nums: List[int]) -> int:
        freq = Counter(nums)
        @cache
        def cal(n):
            if n <= 3:
                return 1 if n == 2 or n == 3 else inf
            return 1 + min(cal(n-2), cal(n-3))
       
        ret = 0
        for val in freq.values():
            tmp = cal(val)
            if tmp == inf:
                return -1
            ret += tmp
        return ret


Python:
return reduce(lambda acc, n: -1 if n < 2 or acc < 0 else acc + n//3 + 1 if n%3 else acc + n//3, Counter(nums).values(), 0)
 
Java:
class Solution {
    public static int minOperations(int[] nums) {
        int ans = 0;
        Arrays.sort(nums);
        int[] freq = new int[nums[nums.length-1]+1];
        for (int num : nums) {
            freq[num]++;
        }
        for (int j : freq) {
             if (j == 1) {
                return -1;
            }
            if (j % 3 != 0) {
                ans += j / 3 + 1;
            } else {
                ans += j / 3;
            }
        }
        return ans;
    }
}
 
C++:
class Solution {
public:
    int minOperations(vector<int>& nums) {
        unordered_map<int,int> mp;
        int res = 0;
        for(int i : nums){
            mp[i]++;
        }
        for(auto &pair : mp){
            int se = pair.second;
            if(se == 1) return -1;
            res += se / 3;
            if(se % 3) res++;
        }
        return res;
    }
};
 
01/04/2024:
Python:
class Solution:
    def minOperations(self, nums: List[int]) -> int:
        freq = Counter(nums)
        @cache
        def cal(n):
            if n <= 3:
                return 1 if n == 2 or n == 3 else inf
            return 1 + min(cal(n-2), cal(n-3))
      
        ret = 0
        for val in freq.values():
            tmp = cal(val)
            if tmp == inf:
                return -1
            ret += tmp
        return ret


Python:
return reduce(lambda acc, n: -1 if n < 2 or acc < 0 else acc + n//3 + 1 if n%3 else acc + n//3, Counter(nums).values(), 0)
vcl DP nữa, lấy đao cát cổ gà quá
 
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.987
Quay lại
Lên đầu trang