LeetCode题解 —— 三倍快乐 很难不爱,重难点整理

题目描述:无重复字符的最长子串(中等)


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

示例:

输入:s = “abcabcbb”

输出:3

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

输入:s = “bbbbb”

输出:1

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

输入:s = “pwwkew”

输出:3

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

输入:s = “”

输出:0

解题思路

刚开始是想用数组存放字符,然后循环进行比较,判断字符是否存在,最后返回最长的子串,然后发现难以实现,有一个问题解决起来太过于麻烦。。然后就果断换一种方式,想起来使用去重的集合,定义一个HashSet集合,该集合可以自动去重,用于循环将字符依次存放到该集合,再用循环进行判断集合中是否有该字符 (此处的判断是写在另一个方法内的,这里调用该方法进行判断),然后再记录集合的长度,重置集合,最后获取最大的长度并返回。

代码实现

//自己做的最优解,时间复杂度:O(N^2)
//用时:一个小时。。
public static int lengthOfLongestSubstring2(String s) {
    //计长度
    int k = 1;
    //最大的长度
    int max = 0;
    //设置Set集合
    HashSet<Character> hashSet = new HashSet<Character>();
    //判断字符串是否为空
    if (s.length() != 0) {
        //循环字符串
        for (int i = 0; i < s.length(); i++) {
            //赋值给集合
            hashSet.add(s.charAt(i));
            //循环字符的后一位
            for (int j = i + 1; j < s.length(); j++) {
                //判断集合中是否存在字符
                if (!ifTrue(hashSet, s.charAt(j))) {
                    //不存在就添加到集合
                    hashSet.add(s.charAt(j));
                } else break;
                //记录集合长度
                k = hashSet.size();
            }
            //集合重置
            hashSet.clear();
            //判断并赋值
            if (k > max) {
                max = k;
            }
        }
    }
    return max;
}
//判断集合中是否有字符c
public static boolean ifTrue(HashSet<Character> hashSet, char c) {
    boolean b = false;
    for (Character s : hashSet) {
        if (s == c) {
            return true;
        }
    }
    return b;
}

波仔的解答

//波仔的解答,时间复杂度:O(N)
public static int lengthOfLongestSubstring1(String s) {
    int n = s.length(), ans = 0;
    //定义一个hash表,字符串和长度
    Map<Character, Integer> map = new HashMap<>();
    for (int end = 0, start = 0; end < n; end++) {
        //获取单个字符
        char alpha = s.charAt(end);
        //如果查找到有数据
        if (map.containsKey(alpha)) {
            //更新start
            start = Math.max(map.get(alpha), start);
        }
        //不管存进来没更新一下ans,就是我们得结果
        //end-start+1就是我们统计出来字符串得长度
        ans = Math.max(ans, end - start + 1);
        //存入数据,有重复得在上面已经查找过了,所以一定能找出来
        map.put(s.charAt(end), end + 1);
    }
    return ans;
}

评论区大哥解答

//评论区大哥的解答,时间复杂度:O(N)
public static int lengthOfLongestSubstring(String s) {
    //记录字符上一次出现的位置
    int[] last = new int[128];
    for (int i = 0; i < 128; i++) {
        last[i] = -1;
    }
    int n = s.length();
    int res = 0;
    int start = 0; //窗口开始位置
    for (int i = 0; i < n; i++) {
        //获取当前字符的ASCII码
        int index = s.charAt(i); //a --97
        //获取字符出现的最大下标值
        start = Math.max(start, last[index] + 1);
        //获取最大长度的子串
        res = Math.max(res, i - start + 1);
        //下标值存放到数组
        last[index] = i;
    }
    return res;
}

总结

刚开始的解题思路不对,绕了很久也花了很多时间也没做出来,后面用集合才勉强做出来,先把思路确定好了再行动,写代码的效率应该会高些。后面看了小波波和评论区大哥的解答,才发现是我肤浅了,是我没想到的方法,逻辑性比较强,下次再遇到这种类型的题,我必定将它拿捏!

三倍快乐

====


力扣第四题


题目描述:寻找两个正序数的中位数(困难)


给定两个大小分别为mn的正序 (从小到大)数组nums1nums2。请你找出并返回这两个正序数组的中位数。

示例:

输入:nums1 = [1,3], nums2 = [2]

输出:2.00000

解释:合并数组 = [1,2,3],中位数 2。

输入:nums1 = [1,2], nums2 = [3,4]

输出:2.50000

解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

输入:nums1 = [0,0], nums2 = [0,0]

输出:0.00000

输入:nums1 = [], nums2 = [1]

输出:1.00000

解题思路

刚看到这题目就有一个疑问,这么简单的题咋会定义为困难哦,也没管那么多,先实现了再说,想到的就是把两个数组合并到一个新数组,然后用arrays中的sort方法排序,最后判断数组的长度,算出中位数并返回。

代码实现

//自己所写的最优解,时间复杂度:O(N)
//用时:十五分钟
public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
    //定义变量
    double num = 0;
    //创建一个新数组,用于存放给出的两个数组值
    int[] nums3 = new int[nums1.length + nums2.length];
    //循环将第一个数组值赋值给新数组
    for (int i = 0; i < nums1.length; i++) {
        nums3[i] = nums1[i];
    }

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

结尾

查漏补缺:Java岗 千+道面试题Java基础+全家桶+容器+反射+异常等

这不止是一份面试清单,更是一种”被期望的责任“,因为有无数个待面试者,希望从这篇文章中,找出通往期望公司的”钥匙“,所以上面每道选题都是结合我自身的经验于千万个面试题中经过艰辛的两周,一个题一个题筛选出来再次对好答案和格式做出来的,面试的答案也是再三斟酌,深怕误人子弟是小,影响他人仕途才是大过,也希望您能把这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。

由于细节内容实在太多啦,在这里我花了两周的时间把这些答案整理成一份文档了,在这里只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

备注Java)**
[外链图片转存中…(img-tzBNhIYh-1711059639514)]

结尾

[外链图片转存中…(img-sSwsCviz-1711059639514)]

这不止是一份面试清单,更是一种”被期望的责任“,因为有无数个待面试者,希望从这篇文章中,找出通往期望公司的”钥匙“,所以上面每道选题都是结合我自身的经验于千万个面试题中经过艰辛的两周,一个题一个题筛选出来再次对好答案和格式做出来的,面试的答案也是再三斟酌,深怕误人子弟是小,影响他人仕途才是大过,也希望您能把这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。

由于细节内容实在太多啦,在这里我花了两周的时间把这些答案整理成一份文档了,在这里只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 16
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值