一、简单:
1.罗马数字转整数
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/roman-to-integer
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的代码:
func romanToInt(s string) int {
/*
思路:从罗马数字第一位开始依次扫描,如果后一位大于前一位,则count-=value,反之,count+=value
*/
var symbols = map[byte]int{'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}//利用map建立每个罗马数字与数字的映射
var count int//最后要得出的整数
var a int//罗马数字的位数
a=len(s)
for i:=0;i<=a-1;i++{
value:=symbols[s[i]]//暂存当前位的罗马数字的数值
if i<=(a-2)&&value<symbols[s[i+1]] {
count-=value//后一位大于前一位
}else {
count+=value//前一位大于后一位
}
}
return count
}
func main() {
fmt.Println(romanToInt("XIV"))
}
运算截图:
解题过程中出现的错误:
“if i<=(a-2)&&value<symbols[s[i+1]] {”这一行错写成了“if i<=(a-1)&&value<symbols[s[i+1]] {”导致报错“panic: runtime error: index out of range [3] with length 3
。原因是最高位是a-1,if循环应该在a-2时停止。否则会溢出。
2.两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:将数组里的每个数x枚举,寻找数组中是否有target-x,已经匹配过的x就不用再匹配了。而每一个元素不能被使用两次,所以我们只需要在 x 后面的元素中寻找 target - x。
代码:
func twoSum(nums []int,target int) []int {
m:=len(nums)
kong:=[]int{}
for i:=0;i<=m;i++ {
for j:=i+1;j<=m-1;j++{
if nums[i]+nums[j]==target {
kong=append(kong,i,j)
return kong
}
}
}
return kong
}
func main() {
var a []int=make([]int,4,6)
a[0]=2
a[1]=7
a[2]=11
a[3]=15
fmt.Println(twoSum(a,9))
}
运行截图:
提交截图:
3.回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是。
思路:将数字本身反转,然后将反转后的数字与原始数字进行比较,如果它们是相同的,那么这个数字就是回文。
但是,如果反转后的数字大于 \text{int.MAX}int.MAX,我们将遇到整数溢出问题。
按照第二个想法,为了避免数字反转可能导致的溢出问题,为什么不考虑只反转 \text{int}int 数字的一半?毕竟,如果该数字是回文,其后半部分反转后应该与原始数字的前半部分相同。
func isPalindrom(x int) bool{
var m bool
a:=0
for i:=x;i>0;i/=10{
a=a*10+i%10
}
if a==x {
m=true
}else {
m=false
}
return m
}
运行结果:
提交截图:
示例 1:
输入:x = 121
输出:true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、中等
1.整数翻转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-integer
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
代码:
func Reverse(x int) int {
var reverse int//定义最后的翻转数
for x!=0 {
if reverse < math.MinInt32/10 || reverse > math.MaxInt32/10 {
return 0
}//根据题目要求x必须为二进制
end:=x%10//end是每次x除以10后的余数,乘以10就相当于进一位,每乘一次进一位,这样就可以将位数翻转
x/=10//x=x/10,与前面的x!=0对应,每次都把个位数去掉,慢慢将这个数除尽
reverse=reverse*10+end//将每次的end和10倍的reverse相加所得到的数为最后的翻转数
}
return reverse//将最后的翻转数返回
}
运行结果:
提交截图:
2.适合打劫的日子
你和一群强盗准备打劫银行。给你一个下标从 0 开始的整数数组 security ,其中 security[i] 是第 i 天执勤警卫的数量。日子从 0 开始编号。同时给你一个整数 time 。
如果第 i 天满足以下所有条件,我们称它为一个适合打劫银行的日子:
第 i 天前和后都分别至少有 time 天。
第 i 天前连续 time 天警卫数目都是非递增的。
第 i 天后连续 time 天警卫数目都是非递减的。
更正式的,第 i 天是一个合适打劫银行的日子当且仅当:security[i - time] >= security[i - time + 1] >= … >= security[i] <= … <= security[i + time - 1] <= security[i + time].
请你返回一个数组,包含 所有 适合打劫银行的日子(下标从 0 开始)。返回的日子可以 任意 顺序排列。
示例 1:
输入:security = [5,3,3,3,5,6,2], time = 2
输出:[2,3]
解释:
第 2 天,我们有 security[0] >= security[1] >= security[2] <= security[3] <= security[4] 。
第 3 天,我们有 security[1] >= security[2] >= security[3] <= security[4] <= security[5] 。
没有其他日子符合这个条件,所以日子 2 和 3 是适合打劫银行的日子
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-good-days-to-rob-the-bank
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:题目中第 ii 天适合打劫需满足:第 ii 天前连续 \textit{time}time 天警卫数目都是非递增与第 ii 天后连续 \textit{time}time 天警卫数目都是非递减。只需要预先计算出第 ii 天前警卫数目连续非递增的天数以及第 ii 天后警卫数目连续非递减的天数即可判断第 ii 天是否适合打劫。设第 ii 天前警卫数目连续非递增的天数为left [i],第 ii 天后警卫数目连续非递减的天数为right [i] ,当第 ii 天同时满足 left [i] ≥time,right [i]≥time 时,即可认定第 ii 天适合打劫。
代码:
var a []int = make([]int, 7, 10)
a[0]=5
a[1]=3
a[2]=3
a[3]=3
a[4]=5
a[5]=6
a[6]=2
fmt.Println(goodDaysToRobBank(a,2))
}
func goodDaysToRobBank(security []int, time int) []int {
var ans []int//这个数组是存放最后结果的
n := len(security)
left := make([]int, n)//左边非递减的天数
right := make([]int, n)//右边非递增的天数
for i := 1; i < n; i++ {
if security[i] <= security[i-1] {
left[i] = left[i-1] + 1
}//计算左边非递减的天数
if security[n-i-1] <= security[n-i] {
right[n-i-1] = right[n-i] + 1
}//计算右边非递增的天数
}
for i := time; i < n-time; i++ {
if left[i] >= time && right[i] >= time {
ans = append(ans, i)//将符合要求的天数加入到ans中
}
}
return ans
}
运行结果:
提交结果: