数组专题~有人十八单手开法拉利,有人二十加在lc刷算法题
2023-09-14 09:16:17 时间
第一题:力扣977题:有序数组的平方
解法一:暴力解法
class Solution {
public int[] sortedSquares(int[] nums) {
//先计算
for(int i = 0; i < nums.length; i++) {
nums[i] *= nums[i];
}
//再排序
Arrays.sort(nums);
return nums;
}
}
解法二:双指针
Q1:为什么会想到双指针呢?
A1:因为给的数组本身是一个非递减的数组,最小负数和最大正数应该分布在数组的两端,所以适合双指针。
class Solution {
public int[] sortedSquares(int[] nums) {
int k = nums.length-1;
//定义一个大小和nums相同的数组
int[] result = new int[nums.length];
//前后比较,移动指针
for(int i = 0, j = nums.length - 1; i <= j;) {
if(nums[i] * nums[i] >= nums[j] * nums[j]) {
result[k--] = nums[i] * nums[i];
i++;
} else if(nums[i] * nums[i] < nums[j] * nums[j]) {
result[k--] = nums[j] * nums[j];
j--;
}
}
return result;
}
}
第二题:力扣209题:长度最小的子数组
解题思路:
经典的滑动窗口问题,大概思想就是不断记录窗口的长度,因为要求的是最小窗口,然后以数组开端为窗口开端,不断往后加,直到窗口内的数之和大于等于目标数,我们就开始往外减(也就是开始缩小窗口,窗口开端往右移动),最终从窗口右端到达数组最右端,结束。
代码如下:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//滑窗的开端
int i = 0;
//窗口总和
int sum = 0;
//定义一个最大长度
int result = Integer.MAX_VALUE;
//滑窗的末端
for(int j = 0; j < nums.length; j++) {
sum += nums[j];
//窗口内部缩小开端
while(sum >= target) {
//记录最小窗口
int subLen = j - i + 1;
result = result < subLen ? result : subLen;
sum -= nums[i];
i++;
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}
第三题:力扣904题:水果成篮
解题思路:
此题为滑动窗口系列中的计数问题,fruitFrequence数组记录现在窗口中每种水果的数目,count记录现在窗口中有多少种不同的水果,如果count<=2,那么right指针可以一直向右移动,直到count>2,当count>2时,说明窗口中的水果种类超过2,为了减少水果种类,left指针就要向右移动,移动的同时还要更新fruitFrequence数组,最后取最大值即可。
代码如下:
class Solution {
public int totalFruit(int[] fruits) {
int n = fruits.length;
if (n <= 2){
return n;
}
int total = 2;
int left = 0;
// 计算篮中种类数
int count = 0;
// 计算篮中每种水果出现的次数
int[] fruitFrequence = new int[n];
for (int right = 0; right < n; right++) {
fruitFrequence[fruits[right]] += 1; // 入篮
//等于1说明第一次入篮,count需要加1
if (fruitFrequence[fruits[right]] == 1) {
count+=1;
}
// 篮中超过两种水果
while (count > 2) {
fruitFrequence[fruits[left]] -= 1;
// 等于0说明篮中已经没有fruits[left]水果,count减1
if (fruitFrequence[fruits[left]] == 0) count-=1;
// 移动left
left += 1;
}
// 取窗口最大值
total = Math.max(total, right - left + 1);
}
return total;
}
}
第四题:力扣59题:螺旋矩阵 II
解题思路:
由外圈向里圈顺时针转,一条边一条边的进行处理,注意的是有奇数和偶数的区别,奇数需要特殊处理。
代码如下:
class Solution {
public int[][] generateMatrix(int n) {
//定义一个新数组
int[][] res = new int[n][n];
//计算一下循环的圈数
int loop = n / 2;
//定义起点位置坐标
int startX = 0;
int startY = 0;
//定义控制变量
int control = 1;
//定义填充内容
int count = 1;
//定义奇数时 中间 坐标(需要单独处理)
int mid = n / 2;
//转圈圈
while(loop > 0) {
int i = startX;
int j = startY;
//上层,从左到右
for( ; j < startY + n - control; j++) {
res[startX][j] = count;
count++;
}
//右层,从上到下
for( ; i < startX + n - control; i++) {
res[i][j] = count;
count++;
}
//下层, 从右到左
for( ; j > startY; j--) {
res[i][j] = count;
count++;
}
//左层, 从下到上
for( ; i > startX; i--) {
res[i][j] = count;
count++;
}
//转完一圈之后,更新转圈的条件
startX += 1;
startY += 1;
control += 2;
loop--;
}
//单独处理奇数情况下的中间数
if(n % 2 == 1) {
res[mid][mid] = count;
}
return res;
}
}
第五题:力扣54题:螺旋矩阵
解题思路:
和 第四题:力扣59题 非常类似,都是逐层去解题的,由外至里。确定好四个角的坐标即可,其实代码有好多种,但是万变不离其中,顺着自己的思路写就行。
代码如下:
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> res = new ArrayList<>();
//定义好 坐标位置
int rows = matrix.length;
int columns = matrix[0].length;
int up = 0;
int down = rows - 1;
int left = 0;
int right = columns - 1;
while(left <= right && up <= down) {
//上行,从左往右
for(int column = left; column <= right; column++) {
res.add(matrix[up][column]);
}
//右行,从上往下
for(int row = up + 1; row <= down; row++) {
res.add(matrix[row][right]);
}
if(left < right && up < down) {
//下行,从右往左
for(int column = right - 1; column >= left; column--) {
res.add(matrix[down][column]);
}
//左行,从下往上
for(int row = down - 1; row >= up + 1; row--) {
res.add(matrix[row][left]);
}
}
left++;
right--;
up++;
down--;
}
return res;
}
}
第六题:力扣27题:移除元素
解法一:暴力法
class Solution {
public int removeElement(int[] nums, int val) {
int length = nums.length;
for(int i = 0; i < length; i++) {
if(nums[i] == val) {
for(int j = i + 1; j < length; j++) {
nums[j-1] = nums[j];
}
i--;
length--;
}
}
return length;
}
}
解法二:双指针法
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int fast = 0; fast < nums.length; fast++) {
if(nums[fast] != val) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}
第七题:力扣26题:删除有序数组中的重复项
class Solution {
public int removeDuplicates(int[] nums) {
if(nums.length == 0) {
return 0;
}
int slow = 1;
for(int fast = 1; fast < nums.length; fast++) {
if(nums[fast] != nums[fast-1]) {
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}
第八题:力扣283题:移动零
class Solution {
public void moveZeroes(int[] nums) {
//快慢指针 去除0
int slow = 0;
for(int fast = 0; fast < nums.length; fast++) {
if(nums[fast] != 0) {
nums[slow] = nums[fast];
slow++;
}
}
//除去0之后的全部补0
for(int i = slow; i < nums.length; i++) {
nums[i] = 0;
}
}
}
第九题:力扣844题:比较含退格的字符串
最后这个题解是在官方题解下边粘过来的,我感觉写的很详细了,大家可以参考一下哈!!!
class Solution {
public boolean backspaceCompare(String s, String t) {
int sN = s.length(), tN = t.length();
int i = sN - 1, j = tN - 1;
int skipS = 0, skipT = 0;
while (i >= 0 || j >= 0)
{
// 先找到 s 中第一个需要比较的字符(即去除 # 影响后的第一个待比较字符)
while (i >= 0)
{
if (s.charAt(i) == '#')
{
skipS ++;
i --;
}
else if (skipS > 0)
{
skipS --;
i --;
}
else
{
break;
}
}
// 再找到 t 中第一个需要比较的字符(即去除 # 影响后的第一个待比较字符)
while (j >= 0)
{
if (t.charAt(j) == '#')
{
skipT ++;
j --;
}
else if (skipT > 0)
{
skipT --;
j --;
}
else
{
break;
}
}
// 然后开始比较,注意有下面这个 if 条件的原因是:如果 index = 0 位置上为 '#',则 i, j 会为 -1
// 而 index = -1 的情况应当处理。
if (i >= 0 && j >= 0)
{
// 如果待比较字符不同,return false
if (s.charAt(i) != t.charAt(j))
return false;
}
// (i >= 0 && j >= 0) 为 false 情况为
// 1. i < 0 && j >= 0
// 2. j < 0 && i >= 0
// 3. i < 0 && j < 0
// 其中,第 3 种情况为符合题意情况,因为这种情况下 s 和 t 都是 index = 0 的位置为 '#' 而这种情况下
// 退格空字符即为空字符,也符合题意,应当返回 True。
// 但是,情况 1 和 2 不符合题意,因为 s 和 t 其中一个是在 index >= 0 处找到了待比较字符,另一个没有找到
// 这种情况显然不符合题意,应当返回 False,下式便处理这种情况。
else if (i >= 0 || j >= 0)
return false;
i--;
j--;
}
return true;
}
}
相关文章
- 一个计算数字数组概览的算法2
- Java实现 蓝桥杯 算法训练 Lift and Throw
- Java实现 LeetCode 561 数组拆分 I(通过排序算法改写PS:难搞)
- Java实现蓝桥杯VIP算法训练 数组逆序排列
- Java实现 蓝桥杯VIP 算法训练 求完数
- Java实现 蓝桥杯 算法训练 动态数组使用
- 视频分类算法
- 【算法】深入排序算法的多语言实现
- NLP之TEA之NB/LoR:利用NB(朴素贝叶斯)、LoR(逻辑斯蒂回归)算法(+TfidfVectorizer)对Rotten Tomatoes影评数据集进行文本情感分析—五分类预测
- Python实现哈里斯鹰优化算法(HHO)优化卷积神经网络回归模型(CNN回归算法)项目实战
- 1671. 得到山形数组的最少删除次数-c语言dp算法加前序后序遍历求解-双百代码
- 算法--数组中出现一次的数,其余都出现N次
- 笔试真题解析 ALBB-2015 算法project师实习生机试
- 数据结构图之二(最小生成树--克鲁斯卡尔算法)
- 目标检测算法——人体姿态估计数据集汇总 2(附下载链接)
- KMP模式匹配算法改进---nextval数组