两个数组的交集、有效的完全平方数、字符串中的第一个唯一字符

博主分享了从Java基础到成为架构师的学习路线,包括每日刷LeetCode算法题,如求交集、判断完全平方数等。通过对比自身解法与优化后的高效解法,强调了算法和数据结构的重要性。同时,博主还提供了相关资源和学习社区,鼓励读者一起学习进步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

🍅 Java学习路线:搬砖工逆袭Java架构师

🍅 简介:Java领域优质创作者🏆、优快云哪吒公众号作者✌ 、Java架构师奋斗者💪

🍅 百日刷题计划:第 14 / 100 天。

🍅 扫描主页左侧二维码,加入群聊,一起学习、一起进步 

🍅 欢迎点赞 👍 收藏 ⭐留言 📝 

位于半山腰的城堡酒店坐拥港口美景


算法是进阶架构师的基础,基础不牢,地动山摇,2021-8-14起开始刷题,目标100天,300道LeetCode算法题,分享是学习的最好方式,加油,嗨起来。


1、LeetCode 350.两个数组的交集


题目

给定两个数组,编写一个函数来计算它们的交集。

小编菜解

public static int[] intersect(int[] nums1, int[] nums2) {
    List<Integer> list1 = new ArrayList<>();
    List<Integer> list2 = new ArrayList<>();
    for (int i = 0; i < nums1.length; i++) {
        list1.add(nums1[i]);
    }

    for (int i = 0; i < nums2.length; i++) {
        list2.add(nums2[i]);
    }
    return getIntersection(list1,list2);
}

public static int[] getIntersection(List<Integer> list1, List<Integer> list2) {
    if (list1.size()>list2.size()){
        return getIntersection(list2,list1);
    }
    List<Integer> list = new ArrayList<>();
    for (Integer x : list1){
        if (list2.contains(x)){
            list.add(x);
            list2.remove(x);
        }
    }
    int[] ret = new int[list.size()];
    for (int i = 0; i < list.size(); i++) {
        ret[i] = list.get(i);
    }
    return ret;
}

思路及算法

为了降低空间复杂度,首先遍历较短的数组并在哈希表中记录每个数字以及对应出现的次数,然后遍历较长的数组得到交集。

大佬指点江山

public static int[] intersect(int[] nums1, int[] nums2) {
    if (nums1.length>nums2.length){
        return intersect(nums2,nums1);
    }
    Map<Integer,Integer> map = new HashMap<>();
    for (int num : nums1) {
        int count = map.getOrDefault(num,0) + 1;
        map.put(num,count);
    }
    int[] arr = new int[nums1.length];
    int index = 0;
    for (int num : nums2) {
        int count = map.getOrDefault(num,0);
        if (count > 0){
            arr[index++] = num;
            count--;
            if (count > 0){
                map.put(num,count);
            }else {
                map.remove(num);
            }
        }
    }
    return Arrays.copyOfRange(arr,0,index);
}

list的效率肯定是低于map的,而我的list还要进行增删操作,故而效率低于大佬的解答。 

2、LeetCode 387.有效的完全平方数

题目

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。

进阶:不要 使用任何内置的库函数,如  sqrt 。

小编菜解

public static boolean isPerfectSquare(int num) {
    if (num == 1){
        return true;
    }
    for (int i = 2; i < num; i++) {
        if (num%i == 0 && num/i == i){
            return true;
        }
    }
    return false;
}

提示超出时间限制! 

小编菜解进阶版

public static boolean isPerfectSquare(int num) {
    if (num == 1){
        return true;
    }
    int middle = num/2;
    int left = 2;
    int right = num;
    if (num == middle*middle) {
        return true;
    }else if (num > middle*middle){
        left = middle+1;
    }else{
        right = middle - 1;
    }
    for (int i = left; i <= right; i++) {
        if (num%i == 0 && num/i == i){
            return true;
        }
    }
    return false;
}

仍然超出时间限制! 

大佬指点江山

public static boolean isPerfectSquare(int num) {
    if (num == 1){
        return true;
    }
    long left = 2;
    long right = num/2;
    long middle = 0;
    while (left<=right){
        middle = left+(right - left)/2;
        if (num == middle * middle){
            return true;
        }
        if (num > middle * middle){
            left = middle+1;
        }else {
            right = middle - 1;
        }
    }
    return false;
}

真的是菜,什么是二分查找,每次都要进行二分查找,而不是只进行一次,进行一次和不进行,效率上没有任何区别!

3、LeetCode 387.字符串中的第一个唯一字符

题目

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

小编菜解

public static int firstUniqChar(String s) {
    Map<Character,Integer> map = new LinkedHashMap<>();
    //将字符和个数放入map中
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (map.containsKey(c)){
            map.put(c,map.get(c)+1);
        }else{
            map.put(c,1);
        }
    }
    //找到第一个值为1的key,因为是LinkedHashMap,所以顺序和字符串顺序一致
    char find = 0;
    for(Map.Entry<Character,Integer> entry : map.entrySet()){
        if (entry.getValue() == 1){
            find = entry.getKey();
            break;
        }
    }
    //再通过找到的第一个唯一字符,找到它的位置
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == find){
            return i;
        }
    }
    return -1;
}

虽然,写出来了,但肯定不是最优解,麻烦的令人发指。 

大佬指点江山

public static int firstUniqChar(String s) {
    Map<Character,Integer> map = new LinkedHashMap<>();
    //将字符和个数放入map中
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        map.put(c,map.getOrDefault(c,0)+1);
    }
    //再通过找到的第一个唯一字符,找到它的位置
    for (int i = 0; i < s.length(); i++) {
        if (map.get(s.charAt(i))==1){
            return i;
        }
    }
    return -1;
}

大体思路是一样的,只不过我多了一步,不应该啊。

推荐阅读

【100天算法入门 - 每日三题 - Day13】反转字符串、反转字符串中的元音字母、两个数组的交集

【100天算法入门 - 每日三题 - Day12】Nim游戏、3的幂、4的幂

【100天算法入门 - 每日三题 - Day11】丢失的数字、移动零、单词规律

【100天算法入门 - 每日三题 - Day10】二叉树的所有路径、各位相加、丑数 

【100天算法入门 - 每日三题 - Day9】汇总区间、2的幂、有效的字母异位词

【100天算法入门 - 每日三题 - Day8】同构字符串、存在重复元素、翻转二叉树

【100天算法入门 - 每日三题 - Day7】验证回文串、只出现一次的数字、多数元素

...

【100天算法入门 - 每日三题 - Day3】回文数、罗马数字转数字、最大公共前缀

【100天算法入门 - 每日三题 - Day2】二分查找、第一个错误的版本、搜索插入位置

【100天算法入门 - 每日三题 - Day1】二叉树的中序遍历、两数之和、整数反转

评论 126
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值