1.数组增删改查
1.1数组的创建与初始化
三种方式初始化数组
// 第一种方式
int[] arr1 = new int[5];
for (int i = 0; i < arr1.length; i++) {
arr1[i] = i+1;
}
// 第二种方式
int[] arr2 = new int[]{1, 2, 3};
// 第三种方式
int[] arr3 = {1,2,3,4};
1.2 查找一个元素
/**
* @param size 已经存放的元素个数
* @param key 待查找的元素
*/
public static int findByElement(int[] arr, int size, int key) {
for (int i = 0; i < size; i++) {
if (arr[i] == key)
return i;
}
return -1;
}
1.3 数组增加元素
思路:先找到要被增加的位置,然后从该位置起,后面的值依次往后移,然后新值插入到该位置
唯一要注意的就是边界的问题
/**
* 数组新增元素
* @param arr 原数组
* @param size 数组有值长度
* @param element 新元素
* @return
*/
public static int[] addByElementSequence(int[] arr, int size, int element) {
// 判断位置是否符合
if (size >= arr.length || size < 0) {
throw new RuntimeException("新增的下标不错误");
}
// 用户输入是从 1 开始,而数组下标从 0 开始,这里 -1
int index = 0;
// 找到符合顺序的位置
for (int i = 0; i < size-1; i++) {
if (element <= arr[i]) {
index = i;
break;
}
}
// 后面的元素往后移
for (int i = size-1; i >= index; i--) {
arr[i+1] = arr[i];
}
arr[index] = element;
return arr;
}
1.4 删除数据
思路:先要找出要删除的字符在数组中是否存在,存在的话就记录当前的
下标
,然后从该下标起,后面依次往前移动,覆盖这个要被删除的值
/**
* 遍历数组,如果发现目标元素,则将其删除,
* 数组的删除就是从目标元素开始,用后续元素依次覆盖前继元素
*
* @param arr 数组
* @param size 数组中的元素个数
* @param key 要删除的目标值
*/
public static int removeByElement(int[] arr, int size, int key) {
int index = -1;
for (int i = 0; i < size; i++) {
if (arr[i] == key) {
index = i;
break;
}
}
if (index != -1) {
for (int i = index + 1; i < size; i++)
arr[i - 1] = arr[i];
size--;
}
return size;
}
2. 算法热身
2.1 单调数组问题
LeetCode 896. 单调数列 判断一个给定的数组是否为单调数组。
如果数组是单调递增或单调递减的,那么它是 单调 的。
如果对于所有 i <= j
,nums[i] <= nums[j]
,那么数组 nums
是单调递增的。 如果对于所有 i <= j
,nums[i]> = nums[j]
,那么数组 nums
是单调递减的。
当给定的数组 nums
是单调数组时返回 true
,否则返回 false
。
思路:定义两个boolean 变量 inc、des,分别为 true,然后循环遍历该数组,如果发现 是递增的(
arr[i] < arr[i+1]
),那么inc = false
,如果发现是递减的(
arr[i] > 2 arr[i+1]
),那么des = false
,最后 比较inc || des
,一方为 true则就是递增或递减,如果两个值都是 flase ,那么就同时出现递增和递减的情况,返回 false。
代码:
public static boolean isSort(int[] arr) {
boolean inc = true;
boolean des = true;
for (int i = 0; i < arr.length - 1; i++) {
// 递增
if (arr[i] < arr[i+1]) {
inc = false;
}
// 递减
if (arr[i] > arr[i+1]) {
des = false;
}
}
/*
*最后再判断两个属性的值,如果有一方为 ture 就是 ture
* 如果全为 false,那么就同时出现递增和递减的情况,返回 false
*/
return inc || des;
}
2.2 数组合并
LeetCode 88. 合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。
请你 合并 nums2
到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1
中。为了应对这种情况,nums1
的初始长度为 m + n
,其中前 m
个元素表示应合并的元素,后 n
个元素为 0
,应忽略。nums2
的长度为 n
。
思路:从两个数组的有值的末尾开始遍历,因为两个都是升序的数组,所以它们最大的值就是在尾部,一开始比较,哪个值大,就插入到 arr1数组的尾部,然后对应的下标 -1
需要注意的是 如果
arr1
的有效值已经空了,比如arr1 = [7,8,9,0,0]
arr2 = [3,4]
,这时候arr1
的值已经全部插入到arr1
的末尾了,i 已经 == -1了,这时候直接 将 arr2 的值填入 arr1中即可,也就是代码中 的 第一个判断语句。
代码:
public static void myMerge(int[] arr1,int m,int[] arr2,int n) {
// 末尾实际下标
int i = m - 1;
int j = n - 1;
int k = arr1.length-1;
// 根据 arr2 的数据量遍历
while (j >= 0) {
if (i < 0 || arr2[j] >= arr1[i]) {
arr1[k] = arr2[j];
j--;
} else {
arr1[k] = arr1[i];
i--;
}
k--;
}
}