乐趣区

关于golang:golangleetcode初级旋转数组存在重复元素

第一题 旋转数组

题目信息

给你一个数组,将数组中的元素向右轮转 k 个地位,其中 k 是非正数。

 

示例 1:

输出: nums = [1,2,3,4,5,6,7], k = 3
输入: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]
示例 2:

输出:nums = [-1,-100,3,99], k = 2
输入:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
 

提醒:

1 <= nums.length <= 105
-231 <= nums[i] <= 231 – 1
0 <= k <= 105
 

进阶:

尽可能想出更多的解决方案,至多有 三种 不同的办法能够解决这个问题。
你能够应用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

解题思路

在 go 语言圣经的 slice 篇中介绍了这样一个例子

上面的 reverse 函数在原内存空间将[]int 类型的 slice 反转,而且它能够用于任意长度的 slice。
// reverse reverses a slice of ints in place.
func reverse(s []int) {

for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {s[i], s[j] = s[j], s[i]
}

}
这里咱们反转数组的利用:
a := […]int{0, 1, 2, 3, 4, 5}
reverse(a[:])
fmt.Println(a) // “[5 4 3 2 1 0]”
一种将 slice 元素循环向左旋转 n 个元素的办法是三次调用 reverse 反转函数,第一次是反转结尾的 n 个元素,而后是反转剩下的元素,最初是反转整个 slice 的元素。(如果是向右循环旋转,则将第三个函数调用移到第一个调用地位就能够了。)

s := []int{0, 1, 2, 3, 4, 5}
// Rotate s left by two positions.
reverse(s[:2])
reverse(s[2:])
reverse(s)
fmt.Println(s) // “[2 3 4 5 0 1]”

因而,应用 reverse 函数,咱们能够轻松的实现任意的右轮转

具体代码

func rotate(nums []int, k int)  {n:=len(nums)
    if k>=n {k=k%n}
    if n==1{fmt.Println(nums)
    }else{reverse(nums[n-k:n])
        reverse(nums[:n-k])
        reverse(nums)
        fmt.Println(nums)
    }
}
func reverse(s []int) {for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {s[i], s[j] = s[j], s[i]
    }
}

代码优化

引自官网解析

func reverse(a []int) {for i, n := 0, len(a); i < n/2; i++ {a[i], a[n-1-i] = a[n-1-i], a[i]
    }
}

func rotate(nums []int, k int) {k %= len(nums)
    reverse(nums)
    reverse(nums[:k])
    reverse(nums[k:])
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/rotate-array/solution/xuan-zhuan-shu-zu-by-leetcode-solution-nipk/
起源:力扣(LeetCode)著作权归作者所有。商业转载请分割作者取得受权,非商业转载请注明出处。

复杂度剖析

工夫复杂度:O(n),其中 n 为数组的长度。每个元素被翻转两次,一共 n 个元素,因而总工夫复杂度为 O(2n)=O(n)。

空间复杂度:O(1)。

另一种解法

见官网解析办法二:环状替换
注:对于 nk=lcm(n,k)gcd(n,k)

有 AB = xaxb,因为 x 是最大公因数,所以 a、b 互质。利用短除法,易得 xab 为 AB 的最小公倍数,定理得证。*

第二题 存在反复元素

题目信息

给定一个整数数组,判断是否存在反复元素。

如果存在一值在数组中呈现至多两次,函数返回 true。如果数组中每个元素都不雷同,则返回 false。

 

示例 1:

输出: [1,2,3,1]
输入: true
示例 2:

输出: [1,2,3,4]
输入: false
示例 3:

输出: [1,1,1,3,3,4,3,2,4,2]
输入: true

解题思路

遍历数组,将数组元素信息存储至哈希表。通过查表失去须要的信息

代码

func containsDuplicate(nums []int) bool {m := map[int] int{}
    for _,num:= range nums{m[num]++
    }
    for _, frequency := range m {
        if frequency > 1{return true}
    }
    return false
}

复杂度剖析

工夫复杂度:O(N),其中 N 为数组的长度。

空间复杂度:O(N),其中 N 为数组的长度。

退出移动版