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

Posted 温文艾尔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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<>()以上是关于LeetCode刷题日记精选例题(附代码+链接)的主要内容,如果未能解决你的问题,请参考以下文章

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

LeetCode刷题日记精选例题(详细解析+代码+链接)

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

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

LeetCode刷题日记精选例题-双指针经典问题总结

刷题那些事Leetcode精选二叉树例题+解析