题目:可被K整除的字数组
题目描述:
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。
示例:
输入:A = [4,5,0,-2,-3,1], K = 5
输出:7
解释:
有 7 个子数组满足其元素之和可被 K = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]
提示:
1 <= A.length <= 30000
-10000 <= A[i] <= 10000
2 <= K <= 10000
分析:这是一场周赛中的题目,当时没考虑时间复杂度,上来就是两层循环,结果超时一直超时,后来看了别题解,前缀和与计数,一开始也没理解,大概思路就是,有一个数组prex记录前缀和例如prex[index]就是前index个元素的和,即,prex[0]=0,pre[1]=A[0],prex[1]=A[0]+A[1]…,然后对每个前缀和进行除模取余操作,记录在一个map中,例如相同的数有多个就证明两个相同的数之差肯定存在一个K的倍数,所以从中任意取两个就能组成一个符合要求的字数组,Cn2,也就是n(n-1)/2,所有的加起来就是总数
代码:
func subarraysDivByK(A []int, K int) int {
m:=make(map[int]int)
sum:=0
ret:=0
m[0]=1
for i:=0;i<len(A);i++{
sum+=A[i]
v:=(sum%K+K)%K
m[v]++
}
for _,v:=range m{
ret+=v*(v-1)/2
}
return ret
}
题目:漂亮数组
题目描述:
对于某些固定的 N,如果数组 A 是整数 1, 2, …, N 组成的排列,使得:
对于每个 i < j,都不存在 k 满足 i < k < j 使得 A[k] * 2 = A[i] + A[j]。
那么数组 A 是漂亮数组。
给定 N,返回任意漂亮数组 A(保证存在一个)。
示例 1:
输入:4
输出:[2,1,4,3]
示例 2:
输入:5
输出:[3,1,2,5,4]
提示:
1 <= N <= 1000
分析:递归求解,知道N==1时返回,先奇数再偶数
代码:
func beautifulArray(N int) []int {
res:=[]int{}
if N==1{
res=append(res,1)
return res
}else{
r1:=beautifulArray((N+1)/2)
for i:=0;i<len(r1);i++{
res=append(res,r1[i]*2-1)
}
r2:=beautifulArray(N/2)
for i:=0;i<len(r2);i++{
res=append(res,r2[i]*2)
}
}
return res
}
题目:独特的电子邮件
题目描述:
用户通过次数 214
用户尝试次数 224
通过次数 220
提交次数 296
题目难度 Easy
每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔。
例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名。
除了小写字母,这些电子邮件还可能包含 ‘.’ 或 ‘+’。
如果在电子邮件地址的本地名称部分中的某些字符之间添加句点(’.’),则发往那里的邮件将会转发到本地名称中没有点的同一地址。例如,"alice.z@leetcode.com” 和 “alicez@leetcode.com” 会转发到同一电子邮件地址。 (请注意,此规则不适用于域名。)
如果在本地名称中添加加号(’+’),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,例如 m.y+name@email.com 将转发到 my@email.com。 (同样,此规则不适用于域名。)
可以同时使用这两个规则。
给定电子邮件列表 emails,我们会向列表中的每个地址发送一封电子邮件。实际收到邮件的不同地址有多少?
示例:
输入:[“test.email+alex@leetcode.com”,“test.e.mail+bob.cathy@leetcode.com”,“testemail+david@lee.tcode.com”]
输出:2
解释:实际收到邮件的是 "testemail@leetcode.com" 和 "testemail@lee.tcode.com"。
提示:
1 <= emails[i].length <= 100
1 <= emails.length <= 100
每封 emails[i] 都包含有且仅有一个 ‘@’ 字符。
分析:主要考察对字符串的操作,一共三种情况,先按@分开两部分,在对第一部分用+分开只要第一部分,最后再将“."替换成空字符串即可,最后合并放进map里,最后返回map的长度
代码:
func numUniqueEmails(emails []string) int {
n:=len(emails)
hash:=make(map[string]int)
for i:=0;i<n;i++{
str:=strings.Split(emails[i],"@")
str[0]=(strings.Split(str[0],"+"))[0]
str[0]=strings.Replace(str[0],".","",-1)
hash[strings.Join(str,"")]++
}
return len(hash)
}
下降路径的最小和
题目描述:
给定一个方形整数数组 A,我们想要得到通过 A 的下降路径的最小和。
下降路径可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列。
示例:
输入:[[1,2,3],[4,5,6],[7,8,9]]
输出:12
解释:
可能的下降路径有:
[1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]
[2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]
[3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]
和最小的下降路径是 [1,4,7],所以答案是 12。
提示:
1 <= A.length == A[0].length <= 100
-100 <= A[i][j] <= 100
分析:
动态规划问题,使用一个n*n的dp数组存储到每个对应节点的最小路径和,要先对边界情况额外赋值,dp[i][j]=min(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+A[i][j],最后找到最后一行的最小值返回即可。
代码:
func minFallingPathSum(A [][]int) int {
n:=len(A)
dp:=[][]int{}
for i:=0;i<n;i++{
arr:=[]int{}
for j:=0;j<n;j++{
arr=append(arr,0)
}
dp=append(dp,arr)
}
for i:=0;i<n;i++ {
dp[0][i] = A[0][i]
}
for j:=1;j<n;j++ {
dp[j][0] = min(dp[j-1][0], dp[j-1][1]) + A[j][0]
dp[j][n-1] = min(dp[j-1][n-1], dp[j-1][n-2]) + A[j][n-1]
for i := 1; i < n-1; i++ {
dp[j][i]=min(dp[j-1][i-1],min(dp[j-1][i],dp[j-1][i+1]))+A[j][i]
}
}
m:=dp[n-1][0]
for i:=1;i<n;i++{
if dp[n-1][i]<m{
m=dp[n-1][i]
}
}
return m
}
func min(a,b int)int{
if a>b{
return b
}
return a
}