本关将以数组作为重点进行学习,该挑战我选择一个数组的增加进行重点记述。增删的基本思路差不多,后续将继续补充
增加一个元素
题目:将给定的元素插入到有序数组的对应位置中
/**
* 自己的练习,按照指定element在升序数组中插入元素
*
* @param arr
* @param size
* @param element
* @return
*/
public static int addByElement(int[] arr, int size, int element) {
// 不能为size > arr.length 因为size必须要保证小于数组长度,才能进行元素插入
if (size >= arr.length) {
System.out.println("Array is full");
return -1;
}
// 这里index不能为size-1 因为需要跟数组中所有的元素进行比较.并且遍历结束后没有比他大的,就插在index索引处
int index = size;
// 因为size是元素个数,正好是最后一个元素的下一个索引,因此不能为size-1
for (int i = 0; i < size; i++) {
if (element < arr[i]) {
index = i;
}
break;
}
// 元素后移 要将前一个索引处的值,移向该索引处。因此要从最后一个元素的后一个索引开始
for (int j = size; j > index; j--) {
arr[j] = arr[j - 1];
}
arr[index] = element;
return index;
}
注释同时对留有的问题进行回答。
这里确实是之前刷算法题没有特别注意的。因为没有专门对数组进行过研究,往往会默认元素个数 == arr.length 在本次挑战中确实重新注意到这一点。
单调数组问题
题目:LeetCode896:判断一个给定的数组是否为单调数组
方法一:
通过两次循环,每一次循环分别去判断是否为单调递增和是否为单调递减。
/**
* 两次循环
*
* @param arr
* @return
*/
public static boolean isSorted(int[] arr) {
boolean increasing = true;
boolean down = true;
for (int i = 0; i < arr.length - 1; i++) {
// 判断是否升序
if (arr[i] <= arr[i + 1]) {
continue;
}
increasing = false;
}
for (int i = 0; i < arr.length - 1; i++) {
// 判断是否降序
if (arr[i] >= arr[i + 1]) {
continue;
}
down = false;
}
return increasing || down;
}
方法二:
通过一次循环即可,在一次循环中,直接对两种情况进行判断。方法一中由于我觉得题解给的实现两种方法有些没必要,就定义了两个变量去分别标记。这恰巧可以简化为方法二,具体实现看代码
/**
* 一次循环
*
* @param arr
* @return
*/
public static boolean isSortedByOne(int[] arr) {
boolean up = true;
boolean down = true;
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
up = false;
}
if (arr[i] < arr[i + 1]) {
down = false;
}
}
return up || down;
}
数组合并
题目:LeetCode88:给你两个按非递减顺序排列的整数数组nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目,请你合并nums2到nums1中,使合并后的数组同样按非递减顺序排列。
示例:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
解释:合并[1,2,3] 和 [2,5,6] 的结果是[1,2,2,3,5,6]
对于两个有序数组的合并,要想不借助排序方法以及新的数组空间。就需要进行一边判断大小一边进行合并。而从数组前端插入,会导致整体数组的移动,时间花销巨大。因此将数组从后面插入,并且由于两个均是有序数组,因此,每个数组的末尾处都是其最大元素所在处。因此,将指针先指向待插入数组的末尾,然后进行两个数组的末尾元素的比较,大的则插入。
/**
* 合并两个有序数组
* @param nums1
* @param nums1_len
* @param nums2
* @param nums2_len
* @return
*/
public static int[] mergeArr(int[] nums1, int nums1_len, int[] nums2, int nums2_len) {
int i = nums1_len + nums2_len - 1;
int len1 = nums1_len - 1;
int len2 = nums2_len - 1;
while (len1 >= 0 && len2 >= 0) {
if (nums1[len1] <= nums2[len2]) {
nums1[i--] = nums2[len2--];
} else if (nums1[len1] > nums2[len2]) {
nums1[i--] = nums1[len1--];
}
}
while (len1 != -1) {
nums1[i--] = nums1[len1--];
}
while (len2 != -1) {
nums1[i--] = nums2[len2--];
}
return nums1;
}