LeetCode刷题 day06
一.第13题.罗马数字转换
1.题目要求
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
要求将输入的罗马数字转为数字,前面比后面数字大的如VII,则表示5+1+1=7,前面数字表示比后面写的,如IV=5-1=4,则是后面数字减前面的数字。
输入: s = “LVIII”
输出: 58
解释: L = 50, V= 5, III = 3.
输入: s = “IV”
输出: 4
1.2解析
- 首先将罗马字符所对应的数字大小储存在哈希表中。
- 设置储存结果的变量ans,初始化为0。
- 循环遍历获取输入的字符串,以及字符所对应哈希表中的value的值大小。
- 判断逻辑如下:
如果前面代表数字大,正常的加即可,
如果前面后一位小,则是后面的数减前面的数。
因为是和后一个字符比较的,防止越界,i需要小于等于倒数第二个字符。
而这边因为设置了结果变量ans,ans++,和ans–进行操作就行了。
1.3代码示例
//先将几个特殊的罗马数字对应储存到哈希表中
Map<Character, Integer> symbolValues = new HashMap<Character, Integer>() {{
put('I', 1);
put('V', 5);
put('X', 10);
put('L', 50);
put('C', 100);
put('D', 500);
put('M', 1000);
}};
public int romanToInt(String s) {
//ans求和,初始化为0
int ans = 0;
int n = s.length();
for (int i = 0; i < n; ++i) {
//获取到当前位置的字符所代表的数字
int value = symbolValues.get(s.charAt(i));
//如果前面代表数字大,正常的加即可,如果前面后一位小,则是后面的数减前面的数
if (i < n - 1 && value < symbolValues.get(s.charAt(i + 1))) {
ans -= value;
} else {
ans += value;
}
}
return ans;
}
二.第15题.三数之和
2.1题目要求
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
2.2思路解析
- 本题要求使三个元素相加结果为0,返回一个三元数组集合,且元素不重复。可以转换为固定一个元素,在后面的元素中找两个元素,使它们之和为0。
- 其中第一个元素我们可以使用最外层的for循环,向后遍历即可。
- 边界条件: 如果数组长度小于3,肯定没法正常输出,结果为空集合。把数组先排序,如果数组的第一个元素大于0,则也返回空集合。
- 将问题转换后,在最外层的for循环里面,就变成了我们最熟悉的双指针问题了,只是多了一个去重的工作。找两个元素之和等于for循环中的元素的相反数就可以了。
- 指针j,k分别从i+1和最后位置向中间靠拢,指针根据元素之和与0的大小比较进行移动,具体代码和注释如下。
2.3代码实现
public static List<List<Integer>> threeSum(int[] num) {
int len=num.length;
List<List<Integer>> res = new ArrayList<>(); //先创建对象
if (len<3)
return res;
Arrays.sort(num); //排序
for (int i=0;i<len;i++){
if (i>0&&num[i]>0) break; //确定第一个数字下标i
if (i>0&&num[i]==num[i-1]) continue; //完成去重
int l=i+1;
int k=len-1; //第2,3指针
while (l<k){
int sum=num[i]+num[l]+num[k];
if (sum==0){
//将该三元组添加到集合中
res.add(Arrays.asList(num[i],num[l],num[k]));
//指针的移动
l++;
k--;
//去重工作,跳过
while (l<k&&num[l]==num[l+1]) l++;
while (l<k&&num[k]==num[k-1]) k--;
}
else if (sum<0) l++; //l指针右移
else if (sum>0) k--; //,k指针左移
}
}
return res;
}