每日编程(35)--leetcode

题目:可被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
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值