thảo luận [Học Tập] Topic thuật toán

  • Người tạo chủ đề Người tạo chủ đề unknowpc90
  • Ngày bắt đầu Ngày bắt đầu
Sao phải dislike nhiều thế nhỉ, bài này hồi sinh viên cũng có làm, dùng phép trừ và vòng lặp là xong mà :surrender:
:feel_good: vì bọn leetcode nó chơi giới hạn độ phức tạp, tăng limit input đến tận INT_MAX và INT_MIN. Nói cách khác, bác mà xài phép trừ là "time limit exceeded" ngay
 
Nay thấy topic này vắng quá. Nên mình sẽ share bài mình mới làm chiều nay.
https://leetcode.com/problems/powx-n/
Yêu cầu là implement hàm pow.
Đọc đề xong thấy bài này easy vkl, k hiểu sao lại là medium, nghĩ trong bụng bài này chắc done trong 1 nốt nhạc. Chỉ cần 1 vòng for chạy từ 0->n rồi nhân lại là xong. dpt là O(n) :D. Đến lúc submit thì bị timeout :beat_brick:.
Lúc đó ngồi nghĩ kỹ lại mới thấy bài này hoàn toàn có thể giải với đpt là O(logN) :p.
tại vì m^n = m^(n/2)*m^(n/2) như vậy mình chỉ cần tính m^(n/2) 1 lần thôi.
C++:
class Solution {
public:
    double myPow(double x, int n) {
        double result = 1;
        x = n > 0 ? x : 1/x;
        for (int i = 0; n != 0; i++){
            result *= n%2!=0 ? x : 1;
            n/=2;
            x = x*x;
        }
        return result;
    }
};
Bài này chắc là kinh điển, nên chắc nhiều anh em cũng từng làm qua rồi. :D

Đáp án của em:

Python:
class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n < 0:
            return self.myPow(1/x, -n)
        elif n == 0:
            return 1.0
        elif n == 1:
            return x
        else:
            if n%2 == 0:
                half = self.myPow(x, n/2)
                return half*half
            else:
                num = int(n/2)
                half = self.myPow(x, num)
                return half * x * half

Các bác rành python chỉ giúp em có cách nào làm gọn code của em hơn không nhỉ.
 
Sửa lần cuối:
Không có gì đặc sắc hay khó khăn lắm, cơ mà bác nào có ý tưởng hay ho không?
rGzdekt.png

Em mới tìm hiểu về map từ 2 hôm trước tự nhiên có bài này ốp vào ngon luôn
O(n.logn) vì cái sort
C++:
#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int a[n];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        multimap<int,int >mp;
        sort(a,a+n,greater<int>() );
        for(int i=0;i<n;i++){
            int d=1;
            while(a[i]==a[i+1]){
                d++;
                i++;
            }
            mp.insert({d,a[i]});
        }
        int b[n];
        int k=0;
        for(auto &it:mp){
            for(int i=0;i<it.first;i++){
                b[k]=it.second;
                k++;
            }
        }
        reverse(b,b+n);
        for(int i=0;i<n;i++) cout<<b[i]<<" ";
        cout<<endl;
    }
}
 
Đáp án của em:

Python:
class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n < 0:
            return self.myPow(1/x, -n)
        elif n == 0:
            return 1.0
        elif n == 1:
            return x
        else:
            if n%2 == 0:
                half = self.myPow(x, n/2)
                return half*half
            else:
                num = int(n/2)
                half = self.myPow(x, num)
                return half * x * half

Các bác rành python chỉ giúp em có cách nào làm gọn code của em hơn không nhỉ.
Ntn đã đủ gọn chưa bạn? :D
Python:
class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n < 0:
            return self.myPow(1/x, -n)
        elif n == 0:
            return 1.0
        elif n == 1:
            return x
        else:
            half = self.myPow(x, n//2)
            return half*half if n%2 == 0 else half * x * half
 
Ntn đã đủ gọn chưa bạn? :D
Python:
class Solution:
    def myPow(self, x: float, n: int) -> float:
        if n < 0:
            return self.myPow(1/x, -n)
        elif n == 0:
            return 1.0
        elif n == 1:
            return x
        else:
            half = self.myPow(x, n//2)
            return half*half if n%2 == 0 else half * x * half

À, em có biết kiểu return này, quên mất, cảm ơn bác :sweet_kiss:.

Mà cái n//2 để lấy kiểu int em dùng python được hơn năm rồi mà chưa biết luôn ấy bác. :surrender:
 
À, em có biết kiểu return này, quên mất, cảm ơn bác :sweet_kiss:.

Mà cái n//2 để lấy kiểu int em dùng python được hơn năm rồi mà chưa biết luôn ấy bác. :surrender:
Python:
class Solution:
    @cache
    def myPow(self, x: float, n: int) -> float:
        if n <= 2:
            return x ** n if n >= 0 else self.myPow(1/x, -n)
        return self.myPow(x, n // 2) * self.myPow(x, n // 2) * self.myPow(x, n % 2)

Đú code ngắn o_Oo_O
 
Python:
class Solution:
    @cache
    def myPow(self, x: float, n: int) -> float:
        if n <= 2:
            return x ** n if n >= 0 else self.myPow(1/x, -n)
        return self.myPow(x, n // 2) * self.myPow(x, n // 2) * self.myPow(x, n % 2)

Đú code ngắn o_Oo_O

Oh cái if not n là check số khac 0 à bác, giờ em mới biết luôn, hỏng kiến thức cơ bản nặng quá :sweat:
 
Python:
class Solution:
    @cache
    def myPow(self, x: float, n: int) -> float:
        if n <= 2:
            return x ** n if n >= 0 else self.myPow(1/x, -n)
        return self.myPow(x, n // 2) * self.myPow(x, n // 2) * self.myPow(x, n % 2)

Đú code ngắn o_Oo_O
Mình nghĩ có thể bỏ @cache đi.
thay
Python:
self.myPow(x, n // 2) * self.myPow(x, n // 2)
thành
Python:
self.myPow(self.myPow(x, n // 2), 2)
Ngắn hơn được 1 khúc nữa. :D
 
Mình nghĩ có thể bỏ @cache đi.
thay
Python:
self.myPow(x, n // 2) * self.myPow(x, n // 2)
thành
Python:
self.myPow(self.myPow(x, n // 2), 2)
Ngắn hơn được 1 khúc nữa. :D

Ngắn vừa chứ ngắn quá sẽ khó đọc bác ơi, như em làm bên data bọn nó code một dòng python mà sau em vô đọc mù mắt, kiểu 1 dòng code mà quá cô đọng, làm quá nhiều thứ ấy.
 
Các bác chia sẻ với em cách các bác tiếp cận Greedy và thuần thục nó được không? Em đần quá mãi mấy hôm nay không thông não được :too_sad::cry:
 
Các bác chia sẻ với em cách các bác tiếp cận Greedy và thuần thục nó được không? Em đần quá mãi mấy hôm nay không thông não được :too_sad::cry:
Mấy cái lý thuyết lúc đầu đọc khó hiểu lắm. Làm nhiều sau đó đọc lại lý thuyết rồi nghiền ngẫm thì sẽ ngộ ra được thôi. :D
 
Mấy cái lý thuyết lúc đầu đọc khó hiểu lắm. Làm nhiều sau đó đọc lại lý thuyết rồi nghiền ngẫm thì sẽ ngộ ra được thôi. :D
Greedy + math ở những bài A trên codeforces khó cực, em tìm ra được cái pattern rồi nhưng vẫn chưa nghĩ ra được công thức Để giải bài
 
Các bác chia sẻ với em cách các bác tiếp cận Greedy và thuần thục nó được không? Em đần quá mãi mấy hôm nay không thông não được :too_sad::cry:
Bản chất của greedy là các bài toán dạng tối ưu hóa và thường yêu cầu khả năng chứng minh được tại sao greedy lại đúng. Trong trường hợp chưa chứng minh được tính đúng đắn, khả năng rất cao là greedy sẽ bị sai nên bác hãy thử tìm phản ví dụ.

Mình nghĩ những người mới học thường bị ngộ nhận greedy là những bài dễ. Greedy thật ra chỉ dễ code thôi, còn để nghĩ ra được cách làm và chứng minh thì lại không dễ chút nào.
 
Độ khó: hard

Cho một chuỗi string s có nội dung là một biểu thức. Hãy tính biểu thức của chuỗi s này và trả về kết quả
Lưu ý: không được sử dụng những hàm dựng sẵn có tác dụng chuyển đổi string thành biểu thức toán học như eval()
Các hạn chế:
Độ dài chuỗi từ 1 cho đến 3 * (10 ^ 5)
Chuỗi chỉ bao gồm các chữ số, phép cộng, phép trừ, dấu ngoặc và khoảng trống
Mọi con số đều thuộc định dạng 32bit

https://leetcode.com/problems/basic-calculator/

Giải bằng JavaScript:

JavaScript:
/**
 * @param {string} s
 * @return {number}
 */
var calculate = function(s) {
    var result = 0;
    var sign = 1;
    var tmp = [];
    for(var i = 0; i < s.length; i++)
        {
            if(s[i] >= '0' && s[i] <= '9')
                {
                    var nums = 0;
                    while(i < s.length && s[i] >= '0' && s[i] <= '9')
                        {
                            nums = nums * 10 + (s[i] - '0');
                            i++;
                        }
                    result = result + (nums * sign);
                    i--;
                }
            if(s[i] == '+')
                {
                    sign = 1;
                }
            if(s[i] == '-')
                {
                    sign = -1;
                }
            if(s[i] == '(')
                {
                    tmp.push(result);
                    tmp.push(sign);
                    result = 0;
                    sign = 1;
                }
            if(s[i] == ')')
                {
                    result = result * tmp[tmp.length - 1];
                    tmp.pop();
                    result = result + tmp[tmp.length - 1];
                    tmp.pop();
                }
        }
    return result;
};
:boss: Bài này nằm trong mục daily challenge hôm nay và cũng là bài hard level đầu tiên tôi sử dụng JavaScript giải thành công. Nói thật bài này xứng đáng với mức medium chứ nó còn dễ hơn kha khá bài medium khác nữa
 
Độ khó: hard

Cho một chuỗi string s có nội dung là một biểu thức. Hãy tính biểu thức của chuỗi s này và trả về kết quả
Lưu ý: không được sử dụng những hàm dựng sẵn có tác dụng chuyển đổi string thành biểu thức toán học như eval()
Các hạn chế:
Độ dài chuỗi từ 1 cho đến 3 * (10 ^ 5)
Chuỗi chỉ bao gồm các chữ số, phép cộng, phép trừ, dấu ngoặc và khoảng trống
Mọi con số đều thuộc định dạng 32bit

https://leetcode.com/problems/basic-calculator/

Giải bằng JavaScript:

JavaScript:
/**
 * @param {string} s
 * @return {number}
 */
var calculate = function(s) {
    var result = 0;
    var sign = 1;
    var tmp = [];
    for(var i = 0; i < s.length; i++)
        {
            if(s[i] >= '0' && s[i] <= '9')
                {
                    var nums = 0;
                    while(i < s.length && s[i] >= '0' && s[i] <= '9')
                        {
                            nums = nums * 10 + (s[i] - '0');
                            i++;
                        }
                    result = result + (nums * sign);
                    i--;
                }
            if(s[i] == '+')
                {
                    sign = 1;
                }
            if(s[i] == '-')
                {
                    sign = -1;
                }
            if(s[i] == '(')
                {
                    tmp.push(result);
                    tmp.push(sign);
                    result = 0;
                    sign = 1;
                }
            if(s[i] == ')')
                {
                    result = result * tmp[tmp.length - 1];
                    tmp.pop();
                    result = result + tmp[tmp.length - 1];
                    tmp.pop();
                }
        }
    return result;
};
:boss: Bài này nằm trong mục daily challenge hôm nay và cũng là bài hard level đầu tiên tôi sử dụng JavaScript giải thành công. Nói thật bài này xứng đáng với mức medium chứ nó còn dễ hơn kha khá bài medium khác nữa
chuẩn rồi, bài này chỉ ở mức medium thôi. Làm xong trong 1 nốt nhạc. :D
 
Không có gì đặc sắc hay khó khăn lắm, cơ mà bác nào có ý tưởng hay ho không?
rGzdekt.png

Em mới tìm hiểu về map từ 2 hôm trước tự nhiên có bài này ốp vào ngon luôn
O(n.logn) vì cái sort
C++:
#include<bits/stdc++.h>
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int a[n];
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        multimap<int,int >mp;
        sort(a,a+n,greater<int>() );
        for(int i=0;i<n;i++){
            int d=1;
            while(a[i]==a[i+1]){
                d++;
                i++;
            }
            mp.insert({d,a[i]});
        }
        int b[n];
        int k=0;
        for(auto &it:mp){
            for(int i=0;i<it.first;i++){
                b[k]=it.second;
                k++;
            }
        }
        reverse(b,b+n);
        for(int i=0;i<n;i++) cout<<b[i]<<" ";
        cout<<endl;
    }
}
ủa thằng multimap này nó tự sắp xếp giảm dần luôn hả thím
 

Thống kê chủ đề

Ngày tạo
unknowpc90,
Người trả lời cuối
Spaghetti Code,
Trả lời
1.460
Lượt xem
154.124
Quay lại
Lên đầu trang