zoukankan      html  css  js  c++  java
  • [算法]移除指定元素&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
    };
    
  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/liuju/p/12520700.html
Copyright © 2011-2022 走看看