LeetCode刷题日记精选例题(附代码+链接)


一、有效字母的异同词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词

来源:力扣(LeetCode)
链接:
题目链接

在这里插入图片描述
解题思路:

因为此题暴力破解的时间复杂度较高,所以我们采用下面的方式

创建一个数组,记录每个字母出现的次数,对s中的每个字符进行遍历并统计其出现次数,再对c2进行遍历,在c2中没出现一次字母,都要使数组中的对应字母次数-1,最后看数组中有没有不等于0的元素,有则返回false,没有则返回true

    public static boolean isAnagram2(String s, String t) {
        int[] arr = new int[26];
        for (char c1:s.toCharArray()){
            arr[c1-'a']+=1;
        }
        for (char c2:t.toCharArray()){
            arr[c2-'a']-=1;
        }
        for (int i : arr) {
            if (i!=0){
                return false;
            }
        }
        return true;
    }

二、数组交集

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

来源:力扣(LeetCode)

链接:题目链接

在这里插入图片描述
解题思路:

每个数组中的元素都可能存在重复的问题,我们可以考虑使用Set集合来存储元素,Set集合可以对数据进行去重,我们只需要在将num2存储进set2时判断num2中的元素是否在set1出现过即可

    public static int[] intersection(int[] nums1, int[] nums2) {
        if (nums1.length==0||nums2.length==0){
            return new int[]{0};
        }

        Set<Integer> set1 = new HashSet<>();
        Set<Integer> set2 = new HashSet<>();
        for (int i : nums1) {
            set1.add(i);
        }

        for (int i : nums2) {
            if (set1.contains(i)){
                set2.add(i);
            }
        }
        int[] arr = new int[set2.size()];
        int index = 0;
        for (Integer integer : set2) {
            arr[index++]=integer;
        }
        return arr;
    }

三、快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 true ;不是,则返回 false 。

来源:力扣(LeetCode)
链接:题目链接

解题思路:

既然有可能无限循环,则其中必有同一个数出现两次,所以判断一个数不是快乐数,他的n会在集合中出现两次,当一个数是快乐数,经过我们的转换,他最终会变成1
在这里插入图片描述

    public static boolean isHappy(int n) {
        Set<Integer> Myset = new HashSet<>();
        while (n!=1&&!Myset.contains(n)){
            int sum = 0;
            Myset.add(n);
            while (n>0){
                sum+=Math.pow(n%10,2);
                n=n/10;
            }
            n=sum;
        }
        return n==1;
    }

四、两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

来源:力扣(LeetCode)
链接:题目链接
在这里插入图片描述
解题思路:

此题我们使用map集合

想要找到两数之和target,我们可以先从第二个数字下手,当3+2的2出现的时候,3必定早就放入了我们的map集合之中,找到匀速下标返回即可

    public static int[] twoSum(int[] nums, int target) {
        int[] arr = new int[2];
        if(nums.length==0||nums==null){
            return arr;
        }
        HashMap<Integer,Integer> map = new HashMap();
        for (int i = 0; i < nums.length; i++) {
            int next = target-nums[i];
            if (map.containsKey(next)){
                arr[1]=i;
                arr[0]=map.get(next);
            }
            map.put(nums[i],i);
        }
        return arr;
    }

五、三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

来源:力扣(LeetCode)
链接:题目链接
在这里插入图片描述
解题思路:

我们首先使数组按从小到大进行排序

使用三个指针,我们要找到a+b+c等于0,遍历num数组,使nums[i]=a,num[left]=b,nums[right]=c

left指针在i与right之间移动,一旦找到某个位置成立,则记录下来,之后由于nums[left]在不断扩大,所以left++,right--,在移动之前再进行去重操作即可

    public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> list = new ArrayList<>();
        //从小到大排序
        Arrays.sort(nums);

        List innerList = new ArrayList<>();
        for (int i = 0; i < nums.length-2; i++) {
            if (nums[i]>0){
                return list;
            }
            if (i>0&&nums[i]==nums[i-1]){
                continue;
            }
            int left = i+1;
            int right = nums.length-1;

            while (left<right){
                int value = nums[i]+nums[left]+nums[right];
                if (value==0){
                    list.add(Arrays.asList(nums[i],nums[left],nums[right]));
                    while (left<right&&nums[right]==nums[right-1])right--;
                    while (left<right&&nums[left]==nums[left+1])left++;
                    left++;
                    right--;
                }else if (value>0){
                    right--;
                }else {
                    left++;
                }
            }
        }
        return list;
    }

六、四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

  • 0 <= a, b, c, d < n
  • a、b、c 和 d 互不相同
  • nums[a] + nums[b] + nums[c] + nums[d] == target

你可以按 任意顺序 返回答案 。

来源:力扣(LeetCode)
链接:题目链接

在这里插入图片描述

解题思路:解题思路其实和三数之和差不多,不过这次我们使用4个指针,遍历数组,将四数之和的问题转化为三数之和的问题

    public static List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> list = new ArrayList<>();
        Arrays.sort(nums);
        if (nums==null||nums.length<4){
            return list;
        }
        for (int i=0;i<nums.length-3;i++){
            int Myt = target-nums[i];
            if (i>0&&nums[i]==nums[i-1]){
                continue;
            }
            for (int j=i+1;j<nums.length-2;j++){
                if (j-1>i&&nums[j]==nums[j-1]){
                    continue;
                }
                int left = j+1;
                int right = nums.length-1;
                while (left<right){
                    int value = nums[j]+nums[left]+nums[right];
                    if (value>Myt){
                        right--;
                    }else if (value<Myt){
                        left++;
                    }else {
                        list.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
                        while (left<right&&nums[left]==nums[left+1])left++;
                        while (left<right&&nums[right]==nums[right-1])right--;
                        left++;
                        right--;
                    }
                }
            }
        }
        return list;
    }

七、四数相加

给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

  • 0 <= i, j, k, l < n
  • nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

来源:力扣(LeetCode)
链接:题目链接

在这里插入图片描述
解题思路:

我们把num1和num2中元素的和看做s1,num3和num4中元素的和看做s2
当s1中-1出现1次时,要想满足nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0,则s2中的1必须出现一次,故我们
只需统计map集合中各元素出现的次数即可

    public static int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
        HashMap<Integer,Integer> sum1 = new HashMap();
        for (int i : nums1) {
            for (int i1 : nums2) {
                sum1.put((i+i1),sum1.getOrDefault(i+i1,0)+1);
            }
        }
        int count = 0;
        for (int i : nums3) {
            for (int i1 : nums4) {
                int value = 0-(i+i1);
                if (sum1.containsKey(value)){
                    count+=sum1.get(value);
                }
            }
        }
        return count;
    }

八、赎金信

为了不在赎金信中暴露字迹,从杂志上搜索各个需要的字母,组成单词来表达意思。

给你一个赎金信 (ransomNote) 字符串和一个杂志(magazine)字符串,判断 ransomNote 能不能由 magazines 里面的字符构成。

如果可以构成,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

来源:力扣(LeetCode)
链接:题目链接
在这里插入图片描述
解题思路:

我们采取从大找小的思路,ransomNote中需要的字符数量比magazine所提供的需要的字符数量要少这一基本点是不变的,所以我们建立一个长度为26的数组arr,记录magazine中各字符出现的次数,在遍历ransomNote数组,其中出现的字符都是我们所需要的,所以每出现一个都在arr的对应位置-1,如果对应位置出现<0的情况,就返回false即可

    public static boolean canConstruct2(String ransomNote, String magazine) {
        int[] arr = new int[26];
        for (char c : magazine.toCharArray()) {
            arr[c-'a']++;
        }
        for (char c : ransomNote.toCharArray()) {
            if (arr[c-'a']>0){
                arr[c-'a']--;
            }else {
                return false;
            }
        }
        return true;
    }

九、反转字符串

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

来源:力扣(LeetCode)
链接:题目链接

在这里插入图片描述

    public static void reverseString(char[] s) {
        for (int i=0,j=s.length-1;i<s.length/2;i++,j--){
            char temp = s[j];
            s[j]=s[i];
            s[i]=temp;
        }
        System.out.println(s);
    }

十、反转字符串2

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

来源:力扣(LeetCode)
链接:题目链接
在这里插入图片描述

    public static String reverseStr(String s, int k) {
        char[] ch = s.toCharArray();
        for (int i=0;i<ch.length;i+=2*k){
            int start = i;
            int end = Math.min(ch.length-1,i+k-1);
            while (start<end){
                char c = ch[start];
                ch[start]=ch[end];
                ch[end]=c;
                start++;
                end--;
            }
        }
        return new String(ch);
    }

十一、字母异位分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母都恰好只用一次

来源:力扣(LeetCode)
链接:题目链接
在这里插入图片描述
解题思路,如果遍历比较的话太过于麻烦,我们可以将不同的异位词通过sort方法进行排序转化中间态进行判断

    public static List<List<String>> groupAnagrams(String[] strs) {
        HashMap<String,List<String>> map = new HashMap();
        List<List<String>> list = new ArrayList<>();
        List<String> innList = new ArrayList<>();
        for (String str : strs) {
            char[] chars = str.toCharArray();
            Arrays.sort(chars);
            String key = new String(chars);
            List<String> orDefault = map.getOrDefault(key, new ArrayList<>());
            orDefault.add(str);
            map.put(key,orDefault);
        }
        for (String s : map.keySet()) {
            list.add(map.get(s));
        }
        return list;
    }
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

温文艾尔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值