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

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值