Leecode刷题----数据结构----第一天

1、题目描述:

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。

 解题思路:

用了一个HashSet集合来保存数组中出现过的数字。如果在遍历数组时发现某个数字已经在集合中出现过了,就说明数组中至少有两个数字相同,返回true即可。如果遍历完整个数组后都没有发现重复数字,就说明数组中每个元素互不相同,返回false即可。

HashSet底层是通过HashMap来实现的,而HashMap的底层结构为数组+链表JDK 8后改为数组+链表+红黑树

contains方法用来判断Set集合是否包含指定的对象。
语法 boolean contains(Object o)
返回值:如果Set集合包含指定的对象,则返回true;否则返回false。

class Solution {
    public boolean containsDuplicate(int[] nums) {

        Set<Integer> set = new HashSet<>();

        for(int num : nums){
            if(set.contains(num)){
                return true;
            }
            set.add(num);
            
        }
        return false;

        }
        

    }

2、题目描述:

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

解题思路 :

使用了一个变量sum来保存当前的子数组和,并使用一个变量maxSum来保存最大的子数组和。在遍历数组时,如果当前子数组和sum加上当前元素nums[i]后仍然大于maxSum,就更新maxSum为sum+nums[i]。如果当前子数组和sum小于0,就将sum重置为0,因为加上一个负数只会使子数组和更小。

class Solution {
   public int maxSubArray(int[] nums) {
    int n = nums.length;
    int maxSum = nums[0];
    int sum = 0;
    for (int i = 0; i < n; i++) {

        sum += nums[i];
        
        if (sum > maxSum) {
            maxSum = sum;
        }

        if (sum < 0) {
            sum = 0;
        }
    }
    return maxSum;
}
}

当前解法时间复杂度为O(n),进阶分治法解题:

分治思想,将数组分成左右两个部分,分别递归求出左右两个部分的最大子数组和,然后再计算跨越中心点的最大子数组和。最后返回这三个值中的最大值即可。

计算跨越中心点的最大子数组和使用了两个指针从中心点向左和向右分别扫描数组,分别计算左侧和右侧的最大子数组和,然后将它们相加即可得到跨越中心点的最大子数组和。

public int maxSubArray(int[] nums) {
    return divideAndConquer(nums, 0, nums.length - 1);
}

private int divideAndConquer(int[] nums, int left, int right) {
    if (left == right) {
        return nums[left];
    }
    int mid = left + (right - left) / 2;
    int leftSum = divideAndConquer(nums, left, mid);
    int rightSum = divideAndConquer(nums, mid + 1, right);
    int crossSum = crossSum(nums, left, right, mid);
    return Math.max(Math.max(leftSum, rightSum), crossSum);
}

private int crossSum(int[] nums, int left, int right, int mid) {
    int leftSum = Integer.MIN_VALUE;
    int sum = 0;
    for (int i = mid; i >= left; i--) {
        sum += nums[i];
        leftSum = Math.max(leftSum, sum);
    }
    int rightSum = Integer.MIN_VALUE;
    sum = 0;
    for (int i = mid + 1; i <= right; i++) {
        sum += nums[i];
        rightSum = Math.max(rightSum, sum);
    }
    return leftSum + rightSum;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值