利用前面的值的和推算后面的值就是前缀和
43
力扣https://leetcode-cn.com/problems/WGki4K/
给你一个整数数组 nums
,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。
思路:可以使用map,也可以使用位数,一定出现三次会导致位一定被3整除,剩下的就是多余的值
func singleNumber(nums []int) int {
nummap:=make(map[int]int)
for i:=0;i<len(nums);i++{
nummap[nums[i]]++
}
for k,v:=range nummap{
if v==1{
return k
}
}
return -1
}
44
力扣https://leetcode-cn.com/problems/aseY1I/
给定一个字符串数组 words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。
思路:按位与的思路,如果两个单词没有重复单词,那么按位与的结果就是0
func SameMapV2(a,b int)bool{
return a&b>0
}
func maxProduct(words []string) int {
var length int
//每个单词的字符组合
varmap:=make(map[string]int)
for i:=0;i<len(words);i++{
var tmp int
for j:=0;j<len(words[i]);j++{
tmp |= 1<<(words[i][j]-'a')
}
varmap[words[i]] = tmp
for z:=i-1;z>=0;z--{
if !SameMapV2(varmap[words[i]],varmap[words[z]]){
//如果两个单词不重复
tmp := len(words[i])*len(words[z])
if tmp > length{
length = tmp
}
}
}
}
return length
}
45
力扣https://leetcode-cn.com/problems/kLl5u1/
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 0 开始计数 ,所以答案数组应当满足 0 <= answer[0] < answer[1] < numbers.length 。假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。
思路:升序,双指针,一个从前,一个从后
func twoSum(numbers []int, target int) []int {
start:=0
end:=len(numbers)-1
for start<end{
tmp:=numbers[start] + numbers[end]
if tmp ==target{
return []int{start,end}
}else if tmp < target{
start++
}else{
end--
}
}
return nil
}
46
力扣https://leetcode-cn.com/problems/1fGaJU/
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a ,b ,c ,使得 a + b + c = 0 ?请找出所有和为 0 且 不重复 的三元组。
思路:先排序,所谓的a+b+c=0就是确定一个值从剩下的找出两个数的和=target
func threeSum(nums []int) [][]int {
if len(nums) < 3 {
return nil
}
var res [][]int
sort.Ints(nums)
for i := 0; i < len(nums); i++ {
if i >= 1 && nums[i] == nums[i-1] {
continue
}
target := nums[i]
start := i + 1
end := len(nums) - 1
indexmap := make(map[string]bool)
for start < end {
tmp := nums[start] + nums[end]
if tmp == -target {
ss := strconv.Itoa(nums[start])
se := strconv.Itoa(nums[end])
if !indexmap[ss+"_"+se] {
indexmap[ss+"_"+se] = true
res = append(res, []int{target, nums[start], nums[end]})
}
start++
end--
} else if tmp < -target {
start++
} else {
end--
}
}
}
return res
}
47
力扣https://leetcode-cn.com/problems/2VG8Kg/
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
思路:滑动窗口的方式保证一次遍历的速度
func minSubArrayLen(target int, nums []int) int {
var sum,res int
start:=0
//不能排序
for i:=0;i<len(nums);i++{
sum = sum + nums[i]
for sum>=target{
tmp := i - start + 1
if res ==0{
res = tmp
}else if res > tmp{
res = tmp
}
sum = sum - nums[start]
start++
}
}
return res
}
48
力扣https://leetcode-cn.com/problems/ZVAVXX/
给定一个正整数数组 nums
和整数 k
,请找出该数组内乘积小于 k
的连续的子数组的个数。
思路:滑动窗口,一看到连续的,且全部都是一个顺序,就说明连续子窗口是可以串联起来的,如果i--j不可以,那么不存在i--n(n>j)可以,就要想到滑动窗口这一思路
func calculate(nums []int) int {
res := nums[0]
for i := 1; i < len(nums); i++ {
res = res * nums[i]
}
return res
}
func numSubarrayProductLessThanK(nums []int, k int) int {
var sum int
var left,right int
for left < len(nums){
for right<len(nums)&&calculate(nums[left:right+1]) < k {
right++
}
sum = sum + right - left
left = left + 1
if right<left{
right = left
}
}
return sum
}
49
力扣https://leetcode-cn.com/problems/QTMn0o/
给定一个整数数组和一个整数 k
,请找到该数组中和为 k
的连续子数组的个数。
思路:第一想法是滑动窗口,但是由于是整数,存在负数的可能性,如果i--j不可以,存在i--n(n>j)可以,用滑动窗口就得遍历每一个终点时间复杂度O(n),所以放弃,我们希望可以以o(n)解决,就可以使用前缀算法
func subarraySum(nums []int, k int) int {
var res,sum int
hashmap:=make(map[int]int)
//使用前缀和算法
//当存在前缀x == sum - k说明一个连续子数组满足条件
//如果sum-k==0说明刚好成立,因此hashmap[0] = 1
hashmap[0] = 1
for i:=0;i<len(nums);i++{
sum = sum + nums[i]
res = res + hashmap[sum-k]
hashmap[sum]++
}
return res
}
50
力扣https://leetcode-cn.com/problems/A1NYOS/给定一个二进制数组
nums
, 找到含有相同数量的 0
和 1
的最长连续子数组,并返回该子数组的长度。
func findMaxLength(nums []int) int {
var res int
var cnt int
hashMap := make(map[int]int)
hashMap[0] = -1
for i, num := range nums {
if num == 0 {
cnt--
} else {
cnt++
}
if v, has := hashMap[cnt]; has {
res = max(res, i-v)
} else {
hashMap[cnt] = i
}
}
return res
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
51
https://leetcode-cn.com/problems/A1NYOS/https://leetcode-cn.com/problems/A1NYOS/
给你一个整数数组 nums ,请计算数组的 中心下标 。
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
思路:充分利用条件,左边和等于右边和,则有sum*2+nums[i]==total成立,return i
//采用前缀和思路,要找下标只需要找到坐标i,使得
//nums[0:i] == nums[i+1:]
func pivotIndex(nums []int) int {
var total int
for i:=0;i<len(nums);i++{
total = total + nums[i]
}
var sum int
for i:=0;i<len(nums);i++{
if sum*2+nums[i]==total{
return i
}
sum = sum + nums[i]
}
return -1
}