Leetcode第四周周賽

用golang做了1,2,4題,第3題golang總是有問題換成c++來做。
代碼地址:leetcode solution(golang)

396. Rotate Function

最暴力的方法莫過於一遍一遍計算。可以得到結果。
第二種方法就是利用了前一次的結果。
假設數組爲
[a,b,c,d]
那麼第一次計算的結果就是:
0*a + 1*b + 2*c + 3*d
第二次計算的結果是(從右往左旋轉):
1*a + 2*b + 3*c + 0*d
和之前的結果比:差值爲:
1*a+1*a+1*a-3*d == 1*a+1*a+1*a+1*d - 3*d
所以基於前一次的結果f,可以得到下一次的結果的計算公式:
t :=f+sum - A[len(A)-i]*len(A)

func maxRotateFunction(A []int) int {
    sum,f:= 0,0
    for i:=0;i<len(A);i++{
        sum += A[i]
        f += i*A[i]
    }
    m := f
    for i:=1;i<len(A);i++{
        t :=f+sum - A[len(A)-i]*len(A)
        if m < t{
            m = t
        }
        f += sum - A[len(A)-i]*len(A)
    }
    return m
}

397. Integer Replacement

很簡單的遞歸計算題目。不過這麼做複雜度比較高,能過也說明Leetcode的test case 有點簡單了。

func integerReplacement(n int) int {
    if n <= 1{
        return 0
    }
    if n %2 == 0{
        return integerReplacement(n/2)+1
    }else{
        t1,t2 := integerReplacement(n+1),integerReplacement(n-1)
        if t1 <t2{
            return t1 +1
        }else{
            return t2 +1
        }
    }
}

398. Random Pick Index

這道題的解法,第一種是創建一個hash表map<int,vector<int>>來保存對應的映射關係。在初始化的時候建表。時間複雜度和空間複雜度都是o(n).在檢索的時候直接查表取隨機值,時間複雜度爲o(1).不過最後會出現MLE錯誤。原因是leetcode這道題考察的點不是hash表,於是將內存限制爲o(1).

//MLE代碼
class Solution {
private:
    unordered_map<int, vector<int>> m;
public:
    Solution(vector<int> nums) {
        srand(time(0));
        for (int i = 0; i<nums.size(); i++){
            if (m.count(nums[i]) == 0){
                vector<int> t;
                t.push_back(i);
                m[nums[i]] = t;
            }
            else{
                m[nums[i]].push_back(i);
            }
        }
    }

    int pick(int target) {
        int r = rand() % m[target].size();
        return m[target][r];
    }
};

這道題實際上考察的是蓄水池抽樣,具體的可以看看這篇Blog
利用蓄水池抽樣算法,就可以在不知道整個數組長度的情況下,就能保證各個元素獲取的概率是相同的。
不過貌似不用蓄水池抽樣的方法也能通過。

class Solution {
    vector<int> num;
public:
    Solution(vector<int> nums) {
        num = nums;
    }

    int pick(int target) {
        int index = -1;
        int count = 0;
        for (int i = 0; i < num.size(); i++){
            if (num[i] == target){
                count++;
                int r = rand() % count + 1;
                if (r == count){
                    index = i;
                }
            }
        }
        return index;
    }
};

順帶吐槽下leetcode的Golang. 這道題讓我意識到Golang不適合在leetcode下刷題用。碰到大數據的題目幾乎都會掛,比如109題和239題。還得發郵件給support才能在後臺改成通過。這道題的golang解法提示WA。但是錯誤的test case在本地運行是可以通過的。

type Solution struct {
    nums []int
}


func Constructor(nums []int) Solution {
    var s Solution
    s.nums = nums
    return s
}


func (this *Solution) Pick(target int) int {
    idx,count := -1,0
    for i:=0;i<len(this.nums);i++{
        if this.nums[i] == target{
            count ++ 
            r := rand.Intn(count) + 1
            if r== count{
                idx = i
            }
        }
    }
    return idx
}

399. Evaluate Division

這種解法最後也能過也是DIAO.
o(n*n)的複雜度。
遍歷兩遍。
第一遍遍歷提供的數據,利用提供的數據計算出所有的兩兩可提供的結果。
比如提供給你 a/b b/c能得到
a/b b/a a/a /b/b a/c c/a這幾個結果。用map記錄這些元素。
第二遍遍歷第一遍所得到的map進行同樣的操作,來二次推導得到的結果。
之後的檢索操作就是查表操作。
沒想到這樣的方法也能過。

func calcEquation(equations [][]string, values []float64, query [][]string) []float64 {
    m := make(map[[2]string]float64)
    //tm := make(map[string]float64)
    for i:=0;i<len(equations);i++{
        a,b :=equations[i][0],equations[i][1]
        m[[2]string{a,b}] =values[i]
        m[[2]string{b,a}] = 1/values[i]
        m[[2]string{a,a}] =1.0
        m[[2]string{b,b}] =1.0
        for j :=i+1;j<len(equations);j++{
            //in here to construct the map
            c,d := equations[j][0],equations[j][1]
            if a!=c &&a!=d && b!=c && b!=d{
                continue// can't get any new info
            }
            if a == c &&b == d || a == d&& b == c{
                continue// can't get any new info
            }
            if a == c{
                m[[2]string{d,b}] = values[i]/values[j]
                m[[2]string{b,d}] = values[j]/values[i]
            }
            if a == d{
                m[[2]string{c,b}] = values[i]*values[j]
                m[[2]string{b,c}] = 1/(values[i]*values[j])
            }
            if b == c{
                m[[2]string{a,d}] = values[i]*values[j]
                m[[2]string{d,a}] = 1/(values[j]*values[i])             
            }
            if b == d{
                m[[2]string{a,c}] = values[i]/values[j]
                m[[2]string{c,a}] = values[j]/values[i]                     
            }
        }
    }
    for k,v := range m{
        a,b := k[0],k[1]
        m[[2]string{a,b}] =v
        m[[2]string{b,a}] = 1/v
        m[[2]string{a,a}] =1.0
        m[[2]string{b,b}] =1.0
        for k1,v1 := range m{
            //in here to construct the map
            c,d := k1[0],k1[1]
            if a!=c &&a!=d && b!=c && b!=d{
                continue// can't get any new info
            }
            if a == c &&b == d || a == d&& b == c{
                continue// can't get any new info
            }
            if a == c{
                m[[2]string{d,b}] = v/v1
                m[[2]string{b,d}] = v1/v
            }
            if a == d{
                m[[2]string{c,b}] = v*v1
                m[[2]string{b,c}] = 1/(v*v1)
            }
            if b == c{
                m[[2]string{a,d}] = v*v1
                m[[2]string{d,a}] = 1/(v*v1)                
            }
            if b == d{
                m[[2]string{a,c}] = v/v1
                m[[2]string{c,a}] = v1/v                    
            }
        }
    }
    tmp := [2]string{"",""}
    var ret []float64
    for i:=0;i<len(query);i++{
        tmp[0],tmp[1] = query[i][0],query[i][1]
        v, ok := m[tmp]
        if ok{
            ret = append(ret,v)
        }else{
            ret = append(ret,-1.0)
        }
    }
    return ret

}
發佈了25 篇原創文章 · 獲贊 9 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章