给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。
你可以按任意顺序返回答案。
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int a = target - nums[i];
if (map.containsKey(a)) {
return new int[]{map.get(a), i};
}
map.put(nums[i], i);
}
return new int[]{};
}
}
思路,先根据题意传入两个参数一个数组,一个目标值,在这里用hashmap键值对存储来进行遍历查询,1.创建hashmap对象,2.for循环来遍历整个初始数组,在里面定义一个a来表示另一个目标数的另一个和数,在map里面查询有a就返还当前的下标i,以及a的下标。如果a
不存在于哈希表中,将当前元素nums[i]
及其下标i
存入哈希表,以便后续元素检查
3. 无重复字符的最长子串
给定一个字符串 s
,请你找出其中不含有重复字符的 最长 子串 的长度。
class Solution {
public int lengthOfLongestSubstring(String s) {
int left =0;
int maxstringlength = 0;
Map<Character ,Integer> Indexcharmap = new HashMap<>();
for (int right = 0; right < s.length(); right++) {
char currentchar = s.charAt(right);
if(Indexcharmap.containsKey(currentchar)&&Indexcharmap.get(currentchar)>=left){
left = Indexcharmap.get(currentchar)+1;
}
Indexcharmap.put(currentchar, right);
maxstringlength= Math.max(maxstringlength,(right-left+1));
}
return maxstringlength;
}
}
-
初始化变量:
left
表示窗口的左边界,初始为0。maxstringlength
记录最长子串的长度,初始为0。Indexcharmap
哈希表存储字符及其最新出现的索引 -
遍历字符串:右指针
right
从0开始遍历字符串的每个字符。 -
处理当前字符
currentchar
:检查重复: 若currentchar
存在于哈希表且其索引≥ left
,说明该字符在当前窗口内重复。移动左边界: 将left
更新为重复字符的下一个位置,确保窗口内无重复。 -
更新哈希表:无论是否重复,都将
currentchar
的最新索引right
存入哈希表,以跟踪字符的最新位置。 -
计算窗口长度:当前窗口长度为
right - left + 1
,更新maxstringlength
为最大值。 -
返回结果:遍历结束后,
maxstringlength
即为最长无重复子串的长度。
举例:
s = "abcabcbb"
为例:
-
right=0
(字符a
),无重复,窗口长度1,max=1
。 -
right=1
(字符b
),窗口长度2,max=2
。 -
right=2
(字符c
),窗口长度3,max=3
。 -
right=3
(字符a
),重复出现(索引0),left=1
,窗口长度3,max=3
。 -
继续遍历,最终最长无重复子串为
"abc"
或"bca"
等,长度3。12. 整数转罗马数字
七个不同的符号代表罗马数字,其值如下:
符号 值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:如果该值不是以 4 或 9 开头,请选择可以从输入中减去的最大值的符号,将该符号附加到结果,减去其值,然后将其余部分转换为罗马数字。 如果该值以 4 或 9 开头,使用 减法形式,表示从以下符号中减去一个符号,例如 4 是 5 (
V
) 减 1 (I
):IV
,9 是 10 (X
) 减 1 (I
):IX
。仅使用以下减法形式:4 (IV
),9 (IX
),40 (XL
),90 (XC
),400 (CD
) 和 900 (CM
)。 给定一个整数,将其转换为罗马数字。只有 10 的次方(I
,X
,C
,M
)最多可以连续附加 3 次以代表 10 的倍数。你不能多次附加 5 (V
),50 (L
) 或 500 (D
)。如果需要将符号附加4次,请使用 减法形式。
class Solution {
public String intToRoman(int num) {
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] symbols = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length && num > 0; i++) {
while (num >= values[i]) {
sb.append(symbols[i]);
num -= values[i];
}
}
return sb.toString();
}
}
-
贪心算法的正确性:
-
罗马数字的规则要求优先使用较大的符号。例如,
58
应表示为LVIII
(50+5+3),而非XXXXXIIII
。 -
通过从大到小遍历
values
,确保每一步都选择当前可能的最大符号。
-
-
减法形式的覆盖性:
-
预定义的减法形式(如
900=CM
,400=CD
)覆盖了所有可能的 4 和 9 场景。 -
如果未包含这些组合,代码会错误生成类似
DCD
(表示 900)或XXXXIIII
(表示 44)。
-
-
时间复杂度与空间复杂度:
-
时间复杂度:
O(1)
,因为values
数组长度固定为 13,无论输入多大,循环次数恒定。 -
空间复杂度:
O(1)
,仅使用固定大小的数组和StringBuilder
。
-