LeetCode - 数组的改变和移动
1. 数组的改变和移动总结
1.1 数组的改变
数组在内存中是一块连续的内存空间,我们可以直接通过下标进行访问,并进行修改。
在Java
中,对于List
类型来说,我们可以通过set(idx, element)
方法将idx
位置的元素进行修改。
1.2 数组的移动
数组的移动不能通过一条语句来实现,通常来说需要通过:插入、删除或者多次交换来实现。
1.3 数组的插入
数组的插入比较麻烦,我们想要在下标为k
的位置插入一个元素时,首先需要将k
及以后的元素往后移动一个位置,然后再将元素插入到k
的位置处。
在Java
中,对于List
类型来说,我们可以通过add(idx, element)
方法将元素添加到idx
下标处。
1.4 数组的删除
删除下标为k
的元素时,需要将k
以后的元素向前移动一个位置。
对于List
类型来说,我们可以通过remove(idx)
方法删除下标为idx
的元素。
2. 题目记录
453. 最小操作次数使数组元素相等
分析题意
给你一个长度为 n
的整数数组,每次操作将会使 n - 1
个元素增加 1
。返回让数组所有元素相等的最小操作次数。
思路分析
这道题有一个很巧妙的思路:由于我们并不关心最终元素相等时的值而只关心操作的次数。所以我们可以将上述问题转化为:每次操作使一个元素减少1
,返回让数组中所有元素相等的最小操作数。这样就简单了:我们想要操作数最小,就必须找到能使所有元素相等的最小值,其实这个值就是数组中的最小值。而操作的次数就是:每个数与最小值的差值之和。
class Solution {
public int minMoves(int[] nums) {
int min = Integer.MAX_VALUE;
for(int i = 0; i < nums.length; i++){
min = Math.min(nums[i], min);
}
int ans = 0;
for(int i = 0; i < nums.length; i++){
ans = ans + nums[i] - min;
}
return ans;
}
}
那么正向思考这个问题应该怎么做呢?
注意到:每次操作都使n-1
个数加1
,也就是所每次操作都会使该数组的sum
加上n-1
。假设最小操作数为a
次,那么此时一定有数学关系式:\(a(n-1) + sum = nx\),其中x
为最终数组中的值。
仅有这一个关系式的约束是不够的,我们还要想清楚的一点就是:原数组中最小的那个数需要操作a
次才能够变为x
,即:\(min + a = x\) (这个比较难想明白)
根据这两个公式我们就可以求出最终的a
了:\(a = sum - n * min\)
class Solution {
public int minMoves(int[] nums) {
int min = Integer.MAX_VALUE;
int sum = 0;
for(int i = 0; i < nums.length; i++){
sum += nums[i];
min = Math.min(nums[i], min);
}
return sum - nums.length * min;
}
}
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
665. 非递减数列
分析题意
给你一个长度为 n
的整数数组 nums
,请你判断在最多改变 1
个元素的情况下,该数组能否变成一个非递减数列。
思路分析
从前往后遍历,找到第一个 a > b
的情况时,对a
或 b
的值进行修改,然后判断修改后的数组是否为非递减数组即可。关键在于:修改 a
还是 修改 b
呢?
这里其实是有两个选择的:
- 对于 [1, 3, 4, 2, 5] ,此时应该修改
b
; - 对于[1, 3, 4, 3, 4], 此时应该修改
a
;
一种简单的方法就是:我们两种情况都尝试,看看是否能够得到非递减数组。
class Solution {
public boolean checkPossibility(int[] nums) {
for(int i = 0; i < nums.length - 1; i++){
if(nums[i] > nums[i + 1]){
int n_1 = nums[i];
int n_2 = nums[i + 1];
// 修改a
nums[i] = n_2;
if(checkMethod(nums)) return true;
// 复位a
nums[i] = n_1;
// 修改b
nums[i + 1] = n_1;
if(checkMethod(nums)) return true;
return false;
}
}
return true;
}
boolean checkMethod(int[] nums){
for(int i = 1; i < nums.length; i++){
if(nums[i - 1] > nums[i]) return false;
}
return true;
}
}
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
283. 移动零
分析题意
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
关键点:保持非零元素的相对顺序。
思路分析
首先排除首尾双指针的思路,因为要保持非零元素的相对顺序,所以不能够使用首尾双指针来做。
首尾双指针是指:左指针找第一个0元素,右指针找第一个非0元素,然后交换两个元素。有点像归并排序。
由于不复制数组,所以大概率还是使用双指针来操作。分析一下,假设我们知道left
左侧都是非零元素,然后在left
右侧找到了一个非零元素,此时只需要将该元素放在left
下标下即可。
基于此思路,我们用left
来标识已经处理元素的右边界,然后通过右指针去寻找下一个非0元素,找到后放置在left
位置并将left
指针右移。
class Solution {
public void moveZeroes(int[] nums) {
int left = 0;
int right = 0;
while(right < nums.length){
if(nums[right] != 0){
nums[left] = nums[right];
left ++;
}
right ++;
}
while(left < nums.length){
nums[left] = 0;
left ++;
}
}
}
复杂度分析
时间复杂度:O(n)
空间复杂度:O(1)
LeetCode - 数组的改变和移动的更多相关文章
- Leetcode数组题*3
目录 Leetcode数组题*3 66.加一 题目描述 思路分析 88.合并两个有序数组 题目描述 思路分析 167.两数之和Ⅱ-输入有序数组 题目描述 思路分析 Leetcode数组题*3 66.加 ...
- Day_12【集合】扩展案例1_利用集合的知识对长度为10的int数组进行去重,产生新数组,不能改变数组中原来数字的大小顺序
分析以下需求,并用代码实现 1.定义一个长度为10的int数组,并存入10个int类型的数据,其中有一些数据是重复的 2.利用集合的知识对数组进行去重,产生新数组,不能改变数组中原来数字的大小顺序 3 ...
- LeetCode 数组分割
LeetCode 数组分割 LeetCode 数组怎么分割可以得到左右最大值的差值的最大 https://www.nowcoder.com/study/live/489/1/1 左右最值最大差 htt ...
- LeetCode数组中重复的数字
LeetCode 数组中重复的数字 题目描述 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次. ...
- LeetCode数组解题模板
一.模板以及题目分类 1.头尾指针向中间逼近 ; ; while (pos1<pos2) { //判断条件 //pos更改条件 if (nums[pos1]<nums[pos2]) pos ...
- LeetCode数组查找问题
简单的二分查找法:(Leetcode704): 注意条件(low<=high) public int search(int[] nums, int target) { int low=0; in ...
- vue数据绑定数组,改变元素时不更新view问题
关于这个问题,官网上说的很清楚官方文档 写个例子HTML<body> <div class="box"> <div v-for="aa i ...
- leetcode 数组类型题总结
1,removeDuplicates(I) int removeDuplicatesI(vector<int>& nums){ // 重新组织数组,同 removeDuplicat ...
- js数组方法 改变原数组和不改变原数组的方法整理
改变原数组: pop(): 删除 arrayObject 的最后一个元素,把数组长度减 1,并且返回它删除的元素的值.如果数组已经为空,则 pop() 不 改变数组,并返回 undefined 值 ...
随机推荐
- SpringBoot数据库管理 - 用flyway对数据库管理和迁移
上文介绍了Liquibase,以及和SpringBoot的集成.除了Liquibase之外,还有一个组件Flyway也是经常被使用到的类似的数据库版本管理中间件.本文主要介绍Flyway, 以及Spr ...
- SpringBoot到底是什么?
摘要:Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程. 本文分享自华为云社区<SpringBoot到底是什么?如何理解p ...
- c:找到出现次数最多的递增数字串
如题,如何在一亿位整数组成的字符串中找到出现次数最多的递增数字串? 答案: #include <stdio.h> #include <string.h> #define MAX ...
- 零基础学Java(13)方法参数
前言 首先回顾一下在程序设计语言中关于如何将参数传递给方法的一些专业术语.按值调用表示方法接收的是调用者提供的值.而按引调用表示方法接收的是调用者提供的变量地址.方法可以修改按引用传递的变量的值,而不 ...
- Powerful Number 筛法
我也不想学筛法了,可你考试时候出一个新筛法就不厚道了吧,我还开始以为这是杜教筛... $tips:$学完杜教筛立马学$Powerful \ Number$筛法,此筛法强悍如斯 $Powerful \ ...
- Java开发学习(二十五)----使用PostMan完成不同类型参数传递
一.请求参数 请求路径设置好后,只要确保页面发送请求地址和后台Controller类中配置的路径一致,就可以接收到前端的请求,接收到请求后,如何接收页面传递的参数? 关于请求参数的传递与接收是和请求方 ...
- Unity获取脚本的CustomEditor(自定义编辑)数据
在此之前,粗略的介绍下 CustomEditor(自定义编辑). Unity对于我们创建的Mono脚本提供了属性面板的展示和修改.默认情况下,Inspector面板中会显示当前脚本类的公开字段(pub ...
- 如何使用.NET 6的IHostedService和BackgroundService?
大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进. 本章是<定制ASP NET 6.0框架系列文章>的第七篇.本文内容和定 ...
- MySQL源码分析之SQL函数执行
1.MySQL中执行一条SQL的总体流程 2.SQL函数执行过程 1.MySQL中执行一条SQL的总体流程 一条包含函数的SQL语句,在mysql中会经过: 客户端发送,服务器连接,语法解析,语句执行 ...
- bat-MD文件转CSV文件
目录 1. bat文件里面写死文件名 2. 拖入文件 注意:每个单元格不能出现字符[|.$.;] 1. bat文件里面写死文件名 @echo off && setlocal enabl ...