用golang做了1,2,4题,第3题golang总是有问题换成c++来做。
代码地址:leetcode solution(golang)
最暴力的方法莫过于一遍一遍计算。可以得到结果。
第二种方法就是利用了前一次的结果。
假设数组为
[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
}
很简单的递归计算题目。不过这么做复杂度比较高,能过也说明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 return t1 +1
}else{
return t2 +1
}
}
}
这道题的解法,第一种是创建一个hash表map
来保存对应的映射关系。在初始化的时候建表。时间复杂度和空间复杂度都是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; iif (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;ithis.nums);i++{
if this.nums[i] == target{
count ++
r := rand.Intn(count) + 1
if r== count{
idx = i
}
}
}
return idx
}
这种解法最后也能过也是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
}