力扣刷题-无重复字符的最长子串与将罗马数字转换为整数

2025-10-14
刷题力扣

题目一原型

给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。


示例 1:


输入: s = "abcabcbb"

输出: 3

解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。注意 "bca" 和 "cab" 也是正确答案。

示例 2:


输入: s = "bbbbb"

输出: 1

解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:


输入: s = "pwwkew"

输出: 3

解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。

请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。



提示:


0 < = s.length < = 5 * 104

s 由英文字母、数字、符号和空格组成


我的思路

我拿一个空的集合,先去判断右边界,如果右边界小于字符串的长度,那么就把这个字符串加到charToAdd 中,如何判断window的集合是否包含了charToAdd 中的字符串,如果没包含则加到window集合中,并且计算出当前的字符串的最长长度,如果包含了就说明window集合当前有重复,但是字符串并没有遍历完,所以需要去删除左侧的一个字符。


代码实现

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        //定义左右边界
        int left = 0;
        int right = 0;
        //定义最长长度
        int maxLength = 0;
        Set<Character> window = new HashSet<>();

        while (right < s.length()) {
            char chatToAdd = s.charAt(right);
            if (!window.contains(chatToAdd)) {
                window.add(chatToAdd);
                right++;
                maxLength = Math.max(maxLength, window.size());
            } else {
                char charToRemove = s.charAt(left);
                window.remove(charToRemove);
                left++;
            }
        }
        return maxLength;
    }
}

题目二原型


我的思路

这道题目的主要难点就是去判断罗马数字的组成逻辑。


这道题目的主要难点就是去判断罗马数字的组成逻辑。


那我总结一下就是


先去声明一个map集合去存放,罗马数字和整数的对应关系。先获取到最后一个罗马字符对应的整数。


在循环中更新总分:


获取当前字符的值 currentValue 和它右边字符的值 rightValue。


从右往左开始遍历,因为我们的核心判断是这样的


如果 currentValue 大于或等于 rightValue,说明是“右加”的情况。记分员在总分板上加上当前值 (result += currentValue)。


如果 currentValue 小于 rightValue,说明是“左减”的情况。记分员在总分板上减去当前值 (result -= currentValue)。


得出结果:循环结束后,result 总分板上的最终分数,就是答案。


具体代码实现

class Solution {
    public int romanToInt(String s) {
        //定义一个集合去存放罗马数字与整数的关系
        Map<Character,Integer> map = new HashMap<>();
        map.put('I',1);
        map.put('V',5);
        map.put('X',10);
        map.put('L',50);
        map.put('C',100);
        map.put('D',500);
        map.put('M',1000);

        //判空
        if(s == null || s.length() == 0){
            return 0;
        }
        //初始化结果
        int result = map.get(s.charAt(s.length()-1));

        //比较右边字符与左边字符的大小
        for(int i = s.length()-2; i >= 0;i-- ){
            //获取当前字符
            int currnetValue = map.get(s.charAt(i));
            //获取当前字符右边的字符
            int rightValue = map.get(s.charAt(i+1));
            //比较当前字符与右边字符的大小
            //具体逻辑:如果 currentValue 大于或等于 rightValue,说明是“右加”的情况。记分员在总分板上加上当前值 (result += currentValue)。
            //如果 currentValue 小于 rightValue,说明是“左减”的情况。记分员在总分板上减去当前值 (result -= currentValue)。
            if(currnetValue >= rightValue){
                result = currnetValue+result;
            }else{
                result = result-currnetValue;
            }
        }
        return result;
    }
}