非递减数组增加元素
要注意判断条件以及查找方向的理解。例如本例是非递减数组,若从左往右查找,判断条件应为element < arr[i],若从右往左查找,则判断条件应为element > arr[i]。
且从左往右查找要进行两次遍历,一次查找,一次后移;而从右往左则两次遍历合为一次,判断完一个元素即可后移。原理很简单因为数组没有负下标,0下标不能往左移动了,想两次合为一次只有比较过的元素才能移动。
从左往右查找:
/**
* @param arr
* @param size 数组已经存储的元素数量
* @param element 待插入的元素元素
* @return index 返回插入元素所在数组下标
*/
public static int addByElementSequence(int[] arr, int size, int element) {
// 数组的现有元素个数应小于数组长度,否则无法增加元素
if (size >= arr.length) return -1;
// 此处 index 初始化不为 0 或 size-1 ,考虑边界问题。比如{3,4,5,8},新增9,若为0则{9,3,4,5,8}。
int index = size;
//找到新元素的插入位置
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]; //index下标开始的元素后移一个位置
}
arr[index] = element;//插入数据
return index;
}
从右往左查找,查找移动数组合并版
public static int addByElementSequence(int[] arr, int size, int element) {
if (size >= arr.length) return -1;
int i = size-1;
for (; i >= 0; i--) {
if (element >= arr[i]) {
arr[i+1] = element;
break;
}else {
arr[i+1] = arr[i];
}
}
if(i==-1) arr[i+1] = element;//防止 size=0 以及循环结束后 i=-1 的情况。
return i+1;
}
删除元素
先查找,若元素存在则删除并移动数组;若不存在,则不动。
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;
}
练习
class Solution {
public boolean isMonotonic(int[] nums) {
return isSorted(nums,true) || isSorted(nums,false);
}
private boolean isSorted(int[] nums, boolean increasing){
int l = nums.length;
for(int i=0;i<l-1;i++){
if(increasing){
if(nums[i]>nums[i+1]) return false;
}else{
if(nums[i]<nums[i+1]) return false;
}
}
return true;
}
}
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int pos = m + n - 1;
while(m>0 && n>0){
nums1[pos--] = nums1[m-1] > nums2[n-1] ? nums1[--m] : nums2[--n];
}
while(n>0){
nums1[pos--] = nums2[--n];
}
}
}