【每日刷题】数组-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

相关文章

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,

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

计算数组的斜率,偏移,R2

模拟Excel中的R2的计算。         public bool fnCheckRear_R2(List<double[]> lRear, int iMinRear, int iMaxRear, ref double dR2)         {             bool bResult = true;             int n = 0;             dou

C# double[] 和Matlab数组MWArray[]转换

C# double[] 转换成MWArray[], 直接赋值就行             MWNumericArray[] ma = new MWNumericArray[4];             double[] dT = new double[] { 0 };             double[] dT1 = new double[] { 0,2 };