移除指定元素
题目
给你一个数组 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
};