题目描述(简单难度)
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
例如给了 nums = [ 3, 2, 2, 3 ]
,val = 3
, 然后我们返回 len = 2
,并且 nums
修改为 [ 2, 2 ]
。
解法一
和上道题一样,我们利用快慢指针,此外我们还得用下反向的思维。快指针 fast
和慢指针 slow
,一直移动 fast
,如果 fast
指向的值不等于给定的 val
,我们就将值赋给 slow
指向的位置,slow
后移一位。如果 fast
指向的值等于 val
了,此时 fast
后移一位就可以了,不做其他操作。
Java
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
int fast = 0;
while(fast<nums.length){
if(nums[fast]!=val){
nums[slow]=nums[fast];
slow++;
}
fast++;
}
return slow;
}
public static void main(String args[]) {
int[] nums= {0,1,2,2,3,0,4,2};
int val=2;
int ans=removeelement(nums,val);
System.out.println(ans);
}
}
时间复杂度:O(n)。
空间复杂度:O(1)。
Python
class Solution(object):
def removeElement(self, nums, val):
slow = 0
fast = 0
while(fast<len(nums)):
if(nums[fast]!=val):
nums[slow]=nums[fast]
slow+=1
fast+=1
return slow
解法二
上边的解法,我们是如果不等于 val
就赋值。但如果按题目的想法,应该是如果等于 val
就移除。我们从正方面去想,也就是等于 val
的话,我们怎么体现移除呢?
题目中有个说明我们没利用到,他告诉我们说 the order of those five elements can be arbitrary,就是说数组的顺序可以随便换,我们怎么充分利用呢?
我们可以这样,如果当前元素等于 val
了,我们就把它扔掉,然后将最后一个值赋值到当前位置,并且长度减去 1。什么意思呢?
比如 1 2 2 4 6,如果 val 等于 2 。那么当移动到 2 的时候,等于 val 了。我们就把最后一个位置的 6 赋值过来,长度减去 1 。就变成了 1 6 2 4。完美!达到了移除的效果。然后当又移动到新的 2 的时候,就把最后的 4 拿过来,变成 1 6 4,达到了移除的效果。看下代码吧。
Java
class Solution {
public int removeElement(int[] nums, int val) {
int n = nums.length;
int i = 0;
while(i < n){
if(nums[i]==val){
nums[i] = nums[n-1];
n = n -1;
}else{
i++;
}
}
return n;
}
}
时间复杂度:同样是 O(n),但如果等于 val 的值比较少,解法二会更有效率些。比如 1 2 3 4,val = 2。解法一 while 循环中将调用 3 次赋值。而解法二中,仅仅当等于 val 的时候赋值 1 次。
空间复杂度:O(1)。
Python
class Solution(object):
def removeElement(self, nums, val):
n = len(nums)
i = 0
while(i < n):
if(nums[i]==val):
nums[i] = nums[n-1]
n = n -1
else:
i+=1
return n
解法三
主要用到双指针
nums = [0,1,2,2,3,0,4,2]
val = 2
i = 0
j = 1
while(j <= len(nums)-1):
if nums[i] == val and nums[j] != val:
nums[i] = nums[j]
nums[j] = val
j += 1
i += 1
elif nums[i] == val and nums[j] == val:
j += 1
elif nums[i] != val:
i += 1
j += 1
print(len(nums) - nums.count(val))
心得
list删除不同位置的数据
pop可以删除不同位置的数据,改变原表的结构,参数为索引位置
# 定义一个示例列表
my_list = ['a', 'b', 'c', 'd', 'e']
# 指定要移动的元素的索引
index_to_move = 2
# 移动元素
element = my_list.pop(index_to_move)
my_list.append(element)
print(my_list)
统计list中指定值出现的次数
# 定义一个示例列表
my_list = ['apple', 'banana', 'cherry', 'apple', 'cherry', 'cherry']
# 指定要统计的值
value_to_count = 'cherry'
# 使用 count() 方法统计指定值的出现次数
count = my_list.count(value_to_count)
print(f"The value '{value_to_count}' appears {count} times in the list.")
统计多个元素出现的频率
使用 collections.Counter
统计多个元素的频率
from collections import Counter
# 定义一个示例列表
my_list = ['apple', 'banana', 'cherry', 'apple', 'cherry', 'cherry']
# 使用 Counter 创建一个计数器对象
counter = Counter(my_list)
# 现在可以获取任何元素的计数
print(f"Count of 'apple': {counter['apple']}")
print(f"Count of 'cherry': {counter['cherry']}")
print(f"Count of 'banana': {counter['banana']}")
参考文献
- https://leetcode.com/problems/remove-element/