力扣哈希表


给定一个整数数组 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;

}

}

 

  1. 初始化变量:left 表示窗口的左边界,初始为0。maxstringlength 记录最长子串的长度,初始为0。Indexcharmap 哈希表存储字符及其最新出现的索引

  2. 遍历字符串:右指针 right 从0开始遍历字符串的每个字符。

  3. 处理当前字符 currentchar检查重复: 若 currentchar 存在于哈希表且其索引 ≥ left,说明该字符在当前窗口内重复。移动左边界: 将 left 更新为重复字符的下一个位置,确保窗口内无重复。

  4. 更新哈希表:无论是否重复,都将 currentchar 的最新索引 right 存入哈希表,以跟踪字符的最新位置。

  5. 计算窗口长度:当前窗口长度为 right - left + 1,更新 maxstringlength 为最大值。

  6. 返回结果:遍历结束后,maxstringlength 即为最长无重复子串的长度。

举例:

 s = "abcabcbb" 为例:

  1. right=0(字符 a),无重复,窗口长度1,max=1

  2. right=1(字符 b),窗口长度2,max=2

  3. right=2(字符 c),窗口长度3,max=3

  4. right=3(字符 a),重复出现(索引0),left=1,窗口长度3,max=3

  5. 继续遍历,最终最长无重复子串为 "abc" 或 "bca" 等,长度3。

    12. 整数转罗马数字

    七个不同的符号代表罗马数字,其值如下:

    符号
    I1
    V5
    X10
    L50
    C100
    D500
    M1000

      罗马数字是通过添加从最高到最低的小数位值的转换而形成的。将小数位值转换为罗马数字有以下规则:如果该值不是以 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 的次方(IXCM)最多可以连续附加 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();
    }
}

  1. 贪心算法的正确性

    • 罗马数字的规则要求优先使用较大的符号。例如,58 应表示为 LVIII(50+5+3),而非 XXXXXIIII

    • 通过从大到小遍历 values,确保每一步都选择当前可能的最大符号。

  2. 减法形式的覆盖性

    • 预定义的减法形式(如 900=CM400=CD)覆盖了所有可能的 4 和 9 场景。

    • 如果未包含这些组合,代码会错误生成类似 DCD(表示 900)或 XXXXIIII(表示 44)。

  3. 时间复杂度与空间复杂度

    • 时间复杂度O(1),因为 values 数组长度固定为 13,无论输入多大,循环次数恒定。

    • 空间复杂度O(1),仅使用固定大小的数组和 StringBuilder

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值