【每日刷题】数组-LC56、LC238、随想录1、LC560

2024-03-03 02:28

本文主要是介绍【每日刷题】数组-LC56、LC238、随想录1、LC560,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. LC56 合并区间

题目链接

  1. Arrays.sort先让intervals里的子数组按照子数组的第一个数字值从小到大排列。
  2. 开一个新数组,newInterval,存放合并好的子数组
  3. 让intervals的当前子数组i的第一个数字与newInterval的当前子数组index的最后一个数字比较大小:如果区间没有重叠,则interval的i加入newInterval; 如果重叠,则与newInterval的区间合并
  4. 注意合并时,并不是newInterval[index][1] = intervals[i][1];
    而是newInterval[index][1] = Math.max(newInterval[index][1], intervals[i][1]);
    因为有可能是这种情况:[1,6],[2,4]——这种情况合并还是[1,6]。
    在这里插入图片描述

秒懂力扣区间题目:重叠区间、合并区间、插入区间

class Solution {public int[][] merge(int[][] intervals) {Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);int[][] newInterval = new int[intervals.length][2];newInterval[0] = intervals[0];int index = 0;for (int i=1; i<intervals.length; i++){if (intervals[i][0] > newInterval[index][1]){index++;newInterval[index] = intervals[i];}else{newInterval[index][1] = Math.max(newInterval[index][1], intervals[i][1]);}}return Arrays.copyOf(newInterval, index+1);}
}

2. LC238除自身以外数组的乘积

题目链接
在这里插入图片描述

class Solution {public int[] productExceptSelf(int[] nums) {int[] left = new int[nums.length];int[] right = new int[nums.length];//leftleft[0] = 1;for (int i=1; i<left.length; i++){left[i] = left[i-1] * nums[i-1];}//rightright[right.length-1] = 1;for (int i=right.length-2; i>=0; i--){right[i] = right[i+1] * nums[i+1];}//合并int[] result = new int[nums.length];for (int i=0; i<nums.length; i++){result[i] = left[i] * right[i];}return result;}
}

3.随想录1、二分查找

题目链接

最重要的是确定左闭右闭区间,所以while条件是<=。因为左闭右闭就是左边区间也包括,右边区间也包括,所以左右区间可以=。如果是开区间,一个区间不包括,一个区间包括,那么两个区间必不能相等。

代码

class Solution {public int search(int[] nums, int target) {int left = 0;int right = nums.length-1;// 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算if (target < nums[0] || target > nums[nums.length - 1]) {return -1;}while(left <= right){int mid = (right+left)/2;if (nums[mid] == target){return mid;}else if (nums[mid] > target){right = mid - 1;}else if (nums[mid] < target){left = mid + 1;}}return -1;}
}

4. LC560 和为k的子数组

题目链接

解法一:
暴力算法
易错:在外层循环时,nums[i] == k了之后不要continue,还有继续内循环。因为可能会有这种情况:满足和为k之后,后面出现了1和-1。此时相加和依然为k。

class Solution {public int subarraySum(int[] nums, int k) {int sum = 0;int count = 0;for (int i=0; i<nums.length; i++){sum = nums[i];if (nums[i] == k){count++;}for (int j=i+1; j<nums.length; j++){sum += nums[j];if (sum == k){count++;}}}return count;}
}

解法二:
前缀和

假设数组的前缀和数组为prefixSum,其中prefixSum[i]表示从数组起始位置到第i个位置的元素之和。

对于任意的两个下标i和j(i < j),如果prefixSum[j] - prefixSum[i] = k,即从第i个位置到第j个位置的元素之和等于k,那么说明从第i+1个位置到第j个位置的连续子数组的和为k。

遍历数组,计算每个位置的前缀和,并使用一个哈希表来存储每个前缀和出现的次数。在遍历的过程中,检查是否存在prefixSum[j] - k的前缀和,如果存在,说明从某个位置到当前位置的连续子数组的和为k,将对应的次数累加到结果中。

这样,通过遍历一次数组,统计出和为k的连续子数组的个数,并且时间复杂度为O(n),其中n为数组的长度。

class Solution {public int subarraySum(int[] nums, int k) {int preSum = 0;int count = 0;Map<Integer, Integer> map = new HashMap<>();map.put(0,1); // 初始化前缀和为0的次数为1for (int i=0; i<nums.length; i++){preSum += nums[i];if (map.containsKey(preSum-k)){count += map.get(preSum-k);}if (map.containsKey(preSum)){map.put(preSum, map.get(preSum)+1);}else{map.put(preSum, 1);}}return count;}
}

!!为什么要初始化前缀和?
如果从数组的开始位置到当前位置的子数组的和恰好等于 k,那么这个子数组的前缀和就是 0,即 sum - k 等于 0。因此,需要初始化一个前缀和为 0 的次数为 1,表示从数组的开始位置到当前位置的子数组的和为 k 的情况。如果不初始化,那么这种情况会被漏掉,导致结果不正确。

这篇关于【每日刷题】数组-LC56、LC238、随想录1、LC560的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/768172

相关文章

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

hdu 1166 敌兵布阵(树状数组 or 线段树)

题意是求一个线段的和,在线段上可以进行加减的修改。 树状数组的模板题。 代码: #include <stdio.h>#include <string.h>const int maxn = 50000 + 1;int c[maxn];int n;int lowbit(int x){return x & -x;}void add(int x, int num){while

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言:柔性数组

数组定义 柔性数组 err int arr[0] = {0}; // ERROR 柔性数组 // 常见struct Test{int len;char arr[1024];} // 柔性数组struct Test{int len;char arr[0];}struct Test *t;t = malloc(sizeof(Test) + 11);strcpy(t->arr,