我在Leetcode上遇到了问题。问题是给定一个数组和一个值,删除该值的所有实例并返回新的长度。 或者你可以阅读它here:
int removeElement(int* nums, int numsSize, int val) {
int *nums_copy;
int count = 0;
int actual_count = 0;
while (actual_count < numsSize) {
if (nums[actual_count] != val) {
nums_copy[count] = nums[actual_count];
count++;
nums_copy = realloc(nums_copy, sizeof(int)* count);
}
actual_count++;
}
nums = nums_copy;
return actual_count;
}
当我尝试使用[1, 2, 2, 3], 2
进行测试时,输出为[1, 2, 2, 3]
,而预期输出为[1, 3]
。
答案 0 :(得分:1)
首先,您不需要重新分配,问题就是删除适当的值。其次,您需要做的是简单地遍历数组并在遇到搜索值时将其向左移动一个位置。并减少结果数。
答案 1 :(得分:0)
显然,您没有在int *nums_copy
之后指定要分配的内存量。使用malloc
中的stdlib
在堆上分配可变数量的内存,或者alloca
在堆栈上分配,但要记住this。
答案 2 :(得分:0)
问题不需要内存分配。所需要的只是将匹配元素放在列表的末尾。这是一个例子。
array = 3, 2, 5, 2, 7, 2
len = 6
val = 2
我们希望实现类似
的目标array = 3, 7, 5, 2, 2, 2
newlength = 3
解决方案以下是一种方法
重复:
从两个标记(索引或指针)开始,一个指向最左边,一个指向最右边的元素
3, 2, 5, 2, 7, 2
L R
如果左标记与'val'匹配,则向左移动。这样做直到匹配停止或它到达正确的标记。
3, 2, 5, 2, 7, 2
L R
(与右标记相反。)如果右标记与'val'匹配,则向右移动。直到匹配停止或到达左标记为止。
3, 2, 5, 2, 7, 2
L R
交换与左右标记对应的元素。
3, 7, 5, 2, 2, 2
L R
转到重复。
答案 3 :(得分:-1)
这应该有效:
int removeElement(int* nums, int numsSize, int val) {
int countNums = 0;
int countCpy = 0;
while (countNums < numsSize) {
if (nums[countNums] != val) {
// Copy the number.
nums[countCpy] = nums[countNums];
++ countCpy;
}
++ countNums;
}
return countCpy;
}
至于为什么你得到的输出是[1,2,2,3],我真的不明白。当你在分配nums_copy之前尝试设置nums_copy [0]时,你应该得到一个段错误。我想这是由于您正在编写的平台。
答案 4 :(得分:-1)
给定代码使用std::vector
,为什么不使用其内置函数?
int removeElement(vector<int>& nums,int val){
vector<int> newNums();
for (int i=0; i<nums.size(); i++){
if (nums[i]!=val){
newNums.push_back(nums[i]);
}
}
return newNums.size();
}
答案 5 :(得分:-1)
int removeElement(int* nums, int numsSize, int val) {
int i, j;
for(i = 0, j = 0 ; i < numsSize ; i++){
if( nums[i] == val ) continue;
nums[ j ] = nums[ i ]; // blind copy
j++;
}
/*
nums = realloc( nums, j * sizeof( int ) );
*/
return j; //actual_count
}