Leetcode训练数据结构入门——数组全刷

Posted 胡毛毛_三月

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode训练数据结构入门——数组全刷相关的知识,希望对你有一定的参考价值。

目录

217. 存在重复元素——简单

题目描述:

题解:

方法一:排序

class Solution 
    public boolean containsDuplicate(int[] nums) 
        Arrays.sort(nums);
        for(int i=0;i<nums.length-1;i++)
            if(nums[i]==nums[i+1])
                return true;
            
        
        return false;
    

复杂度分析

  • 时间复杂度:O(NlogN),其中 N 为数组的长度。需要对数组进行排序。
  • 空间复杂度:O(logN),其中 N 为数组的长度。注意我们在这里应当考虑递归调用栈的深度。

方法二:哈希表

java Set自带去重,如果去重后的长度小于原长度,则返回true

class Solution 
    public boolean containsDuplicate(int[] nums) 
        Set<Integer> arr = new HashSet<Integer>();
        for(int i : nums)
            arr.add(i);
        
        return arr.size()<nums.length?true:false;
    

复杂度分析

  • 时间复杂度:O(N),其中 N 为数组的长度。
  • 空间复杂度:O(N),其中 N 为数组的长度。

53. 最大子数组和——简单

题目描述

题解

方法一:动态规划

class Solution 
    public int maxSubArray(int[] nums) 
        int a = 0;
		int max = nums[0];
		for (int i : nums) 
			a = Math.max(a+i, i);
			max = Math.max(a, max);
		
		return max; 
    

复杂度分析

  • 时间复杂度:O(n),其中 nnums 数组的长度。我们只需要遍历一遍数组即可求得答案。
  • 空间复杂度:O(1)。我们只需要常数空间存放若干变量。

方法二:动态规划

复杂度分析

  • 时间复杂度:O(n),其中 nnums 数组的长度。我们只需要遍历一遍数组即可求得答案。
  • 空间复杂度:O(1)。我们只需要常数空间存放若干变量。

1. 两数之和——简单

题目描述

题解

方法一:暴力枚举

class Solution 
    public int[] twoSum(int[] nums, int target) 
        int n = nums.length;
        for (int i = 0; i < n; ++i) 
            for (int j = i + 1; j < n; ++j) 
                if (nums[i] + nums[j] == target) 
                    return new int[]i, j;
                
            
        
        return new int[0];
    

复杂度分析

方法二:查找表法(哈希表)

class Solution 
    public int[] twoSum(int[] nums, int target) 
    	HashMap<Integer, Integer> hash = new HashMap<>();
    	int arr[] = new int [2];
    	for (int i = 0; i < nums.length; i++) 
			if (hash.containsKey(target-nums[i])) 
//				return new int[] hash.get(target-nums[i]),i;
				arr[0] = hash.get(target-nums[i]);
				arr[1] = i;
			
			hash.put(nums[i], i);
		
    	return arr;
    

复杂度分析


88. 合并两个有序数组——简单

题目描述

题解

方法一:直接合并后排序

class Solution 
    public void merge(int[] nums1, int m, int[] nums2, int n) 
        for (int i = 0; i < n; i++) 
    		nums1[m] = nums2[i];
    		m++;
		
    	Arrays.sort(nums1);
    

复杂度分析

方法二:双指针

class Solution 
    public void merge(int[] nums1, int m, int[] nums2, int n) 
        int p1 = 0, p2 = 0;
        int[] sorted = new int[m + n];
        int cur;
        while (p1 < m || p2 < n) 
            if (p1 == m) 
                cur = nums2[p2++];
             else if (p2 == n) 
                cur = nums1[p1++];
             else if (nums1[p1] < nums2[p2]) 
                cur = nums1[p1++];
             else 
                cur = nums2[p2++];
            
            sorted[p1 + p2 - 1] = cur;
        
        for (int i = 0; i != m + n; ++i) 
            nums1[i] = sorted[i];
        
    

复杂度分析

方法三:

class Solution 
    public void merge(int[] nums1, int m, int[] nums2, int n) 
    	int nums1copy[] = new int[m];
    	System.arraycopy(nums1, 0, nums1copy, 0, m);
    	
    	int p  = 0;		// nums1指针
    	int p1 = 0;		// nums1copy 指针	
    	int p2 = 0;		// nums2 指针
    	
    	while ((p1<m) && (p2<n)) 
			if (nums1copy[p1]<nums2[p2]) 
				nums1[p] = nums1copy[p1];
				p++;
				p1++;
			else 
				nums1[p] = nums2[p2];
				p++;
				p2++;
			
		
    	if (p1<m) 
			System.arraycopy(nums1copy, p1, nums1, p1+p2,m+n-p1-p2);
		
		if (p2<n) 
			System.arraycopy(nums2, p2, nums1, p1+p2, m+n-p1-p2);
		
    

复杂度分析

方法三:// 逆向双指针

class Solution 
    public void merge(int[] nums1, int m, int[] nums2, int n) 
    	int p1 = m-1;
    	int p2 = n-1;
    	int p = m+n-1;
    	while (p1>=0&&p2>=0) 
			if (nums1[p1]<nums2[p2]) 
				nums1[p] = nums2[p2];
				p--;
				p2--;
			else 
				nums1[p] = nums1[p1];
				p--;
				p1--;
			
		
        System.arraycopy(nums2, 0, nums1, 0, p2+1);		// 当nums1 为空的时候直接执行此方法
    

复杂度分析


350. 两个数组的交集 II——简单

题目描述

题解

方法一:使用List集合

class Solution 
    /**
     * 使用集合实现
     */
	public int[] intersect(int[] nums1, int[] nums2) 
		
		List<Integer> list1 = new ArrayList<>();
		for (int i : nums1) 
			list1.add(i);
		
		
		List<Integer> list2 = new ArrayList<>();
		for (int i : nums2) 
			if (list1.contains(i)) 
				list2.add(i);
                // 从list1 除去已匹配的数值
				list1.remove(Integer.valueOf(i));
			
		
		int arr[] = new int[list2.size()];
		int j = 0;
		for (int i : list2) 
			arr[j]=i;
			j++;
		
		return arr;
	

方法二:使用映射实现Map

/**
     * 使用映射实现
     */
    public int[] intersect_3(int[] nums1, int[] nums2) 
        Map<Integer, Integer> map = new HashMap<>(nums1.length);
        // 将 nums1 出现的数值及频次放入映射中
        for (int num : nums1) 
            Integer count = map.get(num);
            if (count == null) 
                map.put(num, 1);
             else 
                map.put(num, ++count);
            
        
        List<Integer> list = new ArrayList<>();
        for (int num : nums2) 
            // 获取映射中该数值出现的频次
            Integer count = map.get(num);
            if (count != null && count != 0) 
                list.add(num);
                // 注意每次匹配后,该数值的频次需要减 1(nums1 和 nums2 匹配的数值的频次要相同)
                map.put(num, --count);
            
        
        int[] res = new int[list.size()];
        for (int i = 0; i < list.size(); i++) 
            res[i] = list.get(i);
        
        return res;
    

方法三:排序预处理(我)

class Solution 
    public int[] intersect(int[] nums1, int[] nums2) 
    	
    	List<Integer> list = new ArrayList<>();
    	Arrays.sort(nums1);
    	Arrays.sort(nums2);
    	
    	for (int i = 0,j=0;i<nums1.length && j<nums2.length;) 
			if (nums1[i]>nums2[j]) 
				j++;
			else if (nums1[i]<nums2[j]) 
				i++;
			else 
				list.add(nums1[i]);
				i++;
				j++;
			
		
    	int arr[] = new int[list.size()];
    	int num = 0;
    	for (int i : list) 
			arr[num] = i;
			num ++;
		
    	return arr;
    

复杂度分析


121. 买卖股票的最佳时机——简单

题目描述

题解

方法一:Dp min、max

思路还是挺清晰的,还是DP思想:

  1. 记录【今天之前买入的最小值】

  2. 计算【今天之前最小值买入,今天卖出的获利】,也即【今天卖出的最大获利】

  3. 比较【每天的最大获利】,取最大值即可

class Solution 
    public int maxProfit(int[] prices) 
    	
    	 if(prices.length <= 1) 
    		 return 0;
    	 
         int min=prices[0];
         int max = 0;
         for (int i = 0; i < prices.length; i++) 
			max = Math.max(max,prices[i]-min)Leetcode训练算法入门——双指针全刷

Leetcode训练剑指 Offer(专项突击)——双指针全刷

pytorch入门 01

LeetCode1394-找出数组中的幸运数

⭐算法入门⭐《前缀和》中等03 —— LeetCode 1248. 统计「优美子数组」

⭐算法入门⭐《哈希表》中等01 —— LeetCode 525. 连续数组