数组-day01-26/27/35

77 阅读2分钟

第一题

题目

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成

思路

image.png

注意,不要拘泥于"前一个数等于后一个数"我该怎么办,跳出这个圈子,想不出来,就跳出这种情况直接用另一种说法,前一个数不等于后一个数嘛

代码

function one(arr) {
    let pre = 0;
    let next = 1;
    while(next < arr.length) {
        if(arr[pre] !== arr[next]) {
            arr[pre + 1] = arr[next];
            pre++;
        }
        next++;
    }
    return pre + 1;
}

代码释义

如上代码:
pre为初始为止0,
next为初始位置为pre的后面一位,
判断前一个数和后一个数是不是不相等,即arr[pre] !== arr[next],那么arr[pre+1]就可以等于arr[next]
否则就不断的next++,直到找到arr[pre] !== arr[next]为止
当arr[pre] !== arr[next],pre终于可以往后走了...

第二题

题目

给你一个数组 nums **和一个值 val,你需要 原地 移除所有数值等于 val **的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

思路

怎么说呢,从上一题获取的思路,考虑不等于的话,真的思路开阔

代码

    public int removeElement(int[] nums, int val) {
        int lenNew = 0;
        for(int i = 0; i< nums.length; i++) {
            if(nums[i] != val){
                nums[lenNew] = nums[i];
                lenNew++;
            };
        };
        return lenNew;
    }

代码释义

设置删除后数组的新长度,默认为0,当有结果不为val的时候,给新的数组赋值,并lenNew+1

第三题

题目

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。

思路

因为只要找到位置就可以,还是已经排序好的数组,直接遍历,遍历到arr[index]不小于val就可以了,下一个位置不是等于就是应该插入的位置

代码

    public int searchInsert(int[] nums, int target) {
        int index = 0;
        while(index < nums.length && nums[index] < target) {
            index++;
        };
        return index;
    }