[算法]移除指定元素&strSr()的实现

移除指定元素

题目

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

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

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

示例 1:

给定 nums = [3,2,2,3], val = 3,

函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。

你不需要考虑数组中超出新长度后面的元素。
示例 2:

给定 nums = [0,1,2,2,3,0,4,2], val = 2,

函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

注意这五个元素可为任意顺序。

你不需要考虑数组中超出新长度后面的元素。

分析

乍一看和昨天的题很像,然而用快慢指针法试了一下,并没有找到合适的思路。
于是用了比较耿直的方法进行尝试

解法

解法一:剪切法(自己命名)

该算法的关键在于剪切掉与指定元素相同的元素,然后将遍历的指针退回一位对剪切到指针位置的元素进行检验。
JS代码:

var removeElement = function(nums, val) {
    for(let i=0;i<nums.length;i++){
        if(nums[i]===val){
            nums.splice(i,1);
            i--;
        }
    }

};

用了一个for,感觉也没有很差?

解法二:覆盖法

该算法的思路在于使用两个指针,一个指针指向"新数组",一个指针指向输入数组。如果第二个指针指向的元素与指定元素不相同,就把它转移到新数组。
事实上可以将原数组与新数组重合,返回新数组指针结束时的位置即可。真乃天人。
JS代码:

var removeElement = function(nums, val) {
    let ans = 0;
    for(const num of nums) {
        if(num != val) {
            nums[ans] = num;
            ans++;
        }
    }
    return ans;
};

解法三:交换法

该算法就更骚了,这个算法的思路在于将数组的无效元素(与指定元素相同的元素)使用有效元素代替。
使用一个指针判断当前元素是否是指定元素,如果是,将数组的最后一个元素赋给它,然后将数组长度减去1.
这里需要注意的是,在转移结束之后,不能使遍历指针后移,必须在下一次循环中继续判断当前位置元素是否符合要求。
且题目中有一个非常重要的要求,就是对最后输出的结果数组的元素顺序不做要求,这不就是为了这个算法铺平道路了嘛。
JS代码:

var removeElement = function(nums, val) {
    let ans = nums.length;
    for (let i = 0; i < ans;) {
        if (nums[i] == val) {
            nums[i] = nums[ans - 1];
            ans--;
        } else {
            i++;
        }
    }
    return ans;
};

值得注意的是i++的位置

strStr()实现

题目

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。

示例 1:

输入: haystack = "hello", needle = "ll"
输出: 2
示例 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1
说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

分析

初学竟然没有想到要用indexOf()(吐血)。

题解

解法一:indexOf()

简单粗暴不解释
JS代码:

var strStr = function(haystack, needle) {
    return haystack.indexOf(needle)
};

解法二:双层循环遍历

双层循环,容易理解,性能很差
JS代码:

var strStr = function(haystack, needle){
    if (needle==="") return 0
    for(var i=0;i<haystack.length;i++){
        if(haystack[i]===needle[0]){
            var flag = true;
            for (var j=1;j<needle.length;j++){
                if (haystack[i+j]!=needle[j]){
                    flag = false
                    break;
                }
            }
            if (flag) return i
        }
    }
    return -1
};

解法三:使用substring

类似于解法二,使用一个方法代替一次循环
很方便就是了

var strStr = function (haystack, needle) {
    if (needle === "") return 0
    for (var i = 0; i < haystack.length; i++) {
        if (haystack[i] === needle[0]) {
            if (haystack.substring(i, i + needle.length) === needle) return i;
        }
    }
    return -1
};
原文地址:https://www.cnblogs.com/liuju/p/12520700.html