给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/remove-element
class Solution { public: int removeElement(vector<int>& nums, int val) { int size = nums.size(); for (int i = 0; i < size; i++) { if(nums[i] == val) { for (int j = i; j < size; j++) { nums[j] = nums[j + 1]; size--; return size; LeetCode代码执行结果: ==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000a0 at pc 0x00000034c580 bp 0x7ffc151294e0 sp 0x7ffc151294d8 READ of size 4 at 0x6020000000a0 thread T0 #2 0x7f87456340b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 0x6020000000a0 is located 0 bytes to the right of 16-byte region [0x602000000090,0x6020000000a0) allocated by thread T0 here: #6 0x7f87456340b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 问题出在这一段代码: for (int j = i; j < size; j++) { nums[j] = nums[j + 1]; 当j = size -1时,nums[j + 1]将超出数组nums的下标。 因此,将此段代码改为: for (int j = i + 1; j < size; j++) { nums[j - 1] = nums[j]; 1. SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 对数组进行操作时,一定要注意数组的可索引范围,保证数组不发生越界。在 Leetcode 中数组越界会给出如下几种报错信息: 1. AddressSanitizer: heap-buffer-overflow on address 报错信息: ==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000032 即if(p == 0||data[p-1]!= now),这样检查到p==0后就不会执行后面的data[p-1],这是因为||是逻辑上的或,前面的语句符合了就不会继续判断了。在力扣执行 s = "){"情况时,循环代码中if(data[p-1]!= now || p ==0)会先判断data[p-1],此时由于p==0,p-1必然造成数组越界从而导致报错,在这里,只需要将两个判断条件替换一下位置即可。这种时候在自己编译器上不一定能检查得出问题,对于力扣来说,这种情况大概率就是。 AddressSanitizer(ASan)是一个快速的内存错误检测工具。它非常快,只拖慢程序两倍左右。可以看到上述代码中,为了易读性,我把程序特殊情况挨着列出来,忘记了顺序问题,应该就是内存泄漏问题,一般出现在数组越界访问之类的。同样会报错,因为也是顺序执行的。 一般情况下是数组越界访问或者数组的下标错误造成的。 今天刷题时遇到这个错误死活找不到原因,因为发现就是数组越界了。 while(f[i]&&i<n)i++;这种写法是错误的,最后i到n了会先访问f[i]引起错误。所以遇到这种循环判断的越界条件一定要放在最开头。 这种小错误都犯了,这题还是得经常刷一段时间不写都忘了。 https://stackoverflow.com/... 我们在刷LeetCode时,往往会出现这种报错信息: AddressSanitizer: heap-buffer-overflow on address 0x602000000040 at pc 0x000000406b5e bp 0x7ffc15cc0320 sp 0x7ffc15cc0318 看到Address, overflow,往往是地址访问越界的错误。因此,遇到这个报错信息,说明数组的下标访问越界。 既然数组下标访问越界,则需要检查代码中与数组下标有关的判断语句、赋值语句或循 引索越界,做题时maxIndex = nums.size(); 应该是maxIndex = nums.size() - 1; ================================================================= ==30==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000000c at pc 0x000000401749 bp 0x7f
class Solution { public: int removeElement(vector<int>& nums, int val) { int size = nums.size(); for (int i = 0; i < size; i++) { if(nums[i] == val) { for (int j = i; j < size; j++) { nums[j] = nums[j + 1]; size--; return size;
LeetCode代码执行结果: ==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000a0 at pc 0x00000034c580 bp 0x7ffc151294e0 sp 0x7ffc151294d8 READ of size 4 at 0x6020000000a0 thread T0 #2 0x7f87456340b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 0x6020000000a0 is located 0 bytes to the right of 16-byte region [0x602000000090,0x6020000000a0) allocated by thread T0 here: #6 0x7f87456340b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 问题出在这一段代码: for (int j = i; j < size; j++) { nums[j] = nums[j + 1]; 当j = size -1时,nums[j + 1]将超出数组nums的下标。 因此,将此段代码改为: for (int j = i + 1; j < size; j++) { nums[j - 1] = nums[j]; 1. SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 对数组进行操作时,一定要注意数组的可索引范围,保证数组不发生越界。在 Leetcode 中数组越界会给出如下几种报错信息: 1. AddressSanitizer: heap-buffer-overflow on address 报错信息: ==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000032 即if(p == 0||data[p-1]!= now),这样检查到p==0后就不会执行后面的data[p-1],这是因为||是逻辑上的或,前面的语句符合了就不会继续判断了。在力扣执行 s = "){"情况时,循环代码中if(data[p-1]!= now || p ==0)会先判断data[p-1],此时由于p==0,p-1必然造成数组越界从而导致报错,在这里,只需要将两个判断条件替换一下位置即可。这种时候在自己编译器上不一定能检查得出问题,对于力扣来说,这种情况大概率就是。 AddressSanitizer(ASan)是一个快速的内存错误检测工具。它非常快,只拖慢程序两倍左右。可以看到上述代码中,为了易读性,我把程序特殊情况挨着列出来,忘记了顺序问题,应该就是内存泄漏问题,一般出现在数组越界访问之类的。同样会报错,因为也是顺序执行的。 一般情况下是数组越界访问或者数组的下标错误造成的。 今天刷题时遇到这个错误死活找不到原因,因为发现就是数组越界了。 while(f[i]&&i<n)i++;这种写法是错误的,最后i到n了会先访问f[i]引起错误。所以遇到这种循环判断的越界条件一定要放在最开头。 这种小错误都犯了,这题还是得经常刷一段时间不写都忘了。 https://stackoverflow.com/... 我们在刷LeetCode时,往往会出现这种报错信息: AddressSanitizer: heap-buffer-overflow on address 0x602000000040 at pc 0x000000406b5e bp 0x7ffc15cc0320 sp 0x7ffc15cc0318 看到Address, overflow,往往是地址访问越界的错误。因此,遇到这个报错信息,说明数组的下标访问越界。 既然数组下标访问越界,则需要检查代码中与数组下标有关的判断语句、赋值语句或循 引索越界,做题时maxIndex = nums.size(); 应该是maxIndex = nums.size() - 1; ================================================================= ==30==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000000c at pc 0x000000401749 bp 0x7f
==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000a0 at pc 0x00000034c580 bp 0x7ffc151294e0 sp 0x7ffc151294d8 READ of size 4 at 0x6020000000a0 thread T0 #2 0x7f87456340b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 0x6020000000a0 is located 0 bytes to the right of 16-byte region [0x602000000090,0x6020000000a0) allocated by thread T0 here: #6 0x7f87456340b2 (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) 问题出在这一段代码: for (int j = i; j < size; j++) { nums[j] = nums[j + 1]; 当j = size -1时,nums[j + 1]将超出数组nums的下标。 因此,将此段代码改为: for (int j = i + 1; j < size; j++) { nums[j - 1] = nums[j]; 1. SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 对数组进行操作时,一定要注意数组的可索引范围,保证数组不发生越界。在 Leetcode 中数组越界会给出如下几种报错信息: 1. AddressSanitizer: heap-buffer-overflow on address 报错信息: ==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000032 即if(p == 0||data[p-1]!= now),这样检查到p==0后就不会执行后面的data[p-1],这是因为||是逻辑上的或,前面的语句符合了就不会继续判断了。在力扣执行 s = "){"情况时,循环代码中if(data[p-1]!= now || p ==0)会先判断data[p-1],此时由于p==0,p-1必然造成数组越界从而导致报错,在这里,只需要将两个判断条件替换一下位置即可。这种时候在自己编译器上不一定能检查得出问题,对于力扣来说,这种情况大概率就是。 AddressSanitizer(ASan)是一个快速的内存错误检测工具。它非常快,只拖慢程序两倍左右。可以看到上述代码中,为了易读性,我把程序特殊情况挨着列出来,忘记了顺序问题,应该就是内存泄漏问题,一般出现在数组越界访问之类的。同样会报错,因为也是顺序执行的。 一般情况下是数组越界访问或者数组的下标错误造成的。 今天刷题时遇到这个错误死活找不到原因,因为发现就是数组越界了。 while(f[i]&&i<n)i++;这种写法是错误的,最后i到n了会先访问f[i]引起错误。所以遇到这种循环判断的越界条件一定要放在最开头。 这种小错误都犯了,这题还是得经常刷一段时间不写都忘了。 https://stackoverflow.com/... 我们在刷LeetCode时,往往会出现这种报错信息: AddressSanitizer: heap-buffer-overflow on address 0x602000000040 at pc 0x000000406b5e bp 0x7ffc15cc0320 sp 0x7ffc15cc0318 看到Address, overflow,往往是地址访问越界的错误。因此,遇到这个报错信息,说明数组的下标访问越界。 既然数组下标访问越界,则需要检查代码中与数组下标有关的判断语句、赋值语句或循 引索越界,做题时maxIndex = nums.size(); 应该是maxIndex = nums.size() - 1; ================================================================= ==30==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000000c at pc 0x000000401749 bp 0x7f
问题出在这一段代码:
for (int j = i; j < size; j++) { nums[j] = nums[j + 1]; 当j = size -1时,nums[j + 1]将超出数组nums的下标。 因此,将此段代码改为: for (int j = i + 1; j < size; j++) { nums[j - 1] = nums[j]; 1. SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 对数组进行操作时,一定要注意数组的可索引范围,保证数组不发生越界。在 Leetcode 中数组越界会给出如下几种报错信息: 1. AddressSanitizer: heap-buffer-overflow on address 报错信息: ==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000032 即if(p == 0||data[p-1]!= now),这样检查到p==0后就不会执行后面的data[p-1],这是因为||是逻辑上的或,前面的语句符合了就不会继续判断了。在力扣执行 s = "){"情况时,循环代码中if(data[p-1]!= now || p ==0)会先判断data[p-1],此时由于p==0,p-1必然造成数组越界从而导致报错,在这里,只需要将两个判断条件替换一下位置即可。这种时候在自己编译器上不一定能检查得出问题,对于力扣来说,这种情况大概率就是。 AddressSanitizer(ASan)是一个快速的内存错误检测工具。它非常快,只拖慢程序两倍左右。可以看到上述代码中,为了易读性,我把程序特殊情况挨着列出来,忘记了顺序问题,应该就是内存泄漏问题,一般出现在数组越界访问之类的。同样会报错,因为也是顺序执行的。 一般情况下是数组越界访问或者数组的下标错误造成的。 今天刷题时遇到这个错误死活找不到原因,因为发现就是数组越界了。 while(f[i]&&i<n)i++;这种写法是错误的,最后i到n了会先访问f[i]引起错误。所以遇到这种循环判断的越界条件一定要放在最开头。 这种小错误都犯了,这题还是得经常刷一段时间不写都忘了。 https://stackoverflow.com/... 我们在刷LeetCode时,往往会出现这种报错信息: AddressSanitizer: heap-buffer-overflow on address 0x602000000040 at pc 0x000000406b5e bp 0x7ffc15cc0320 sp 0x7ffc15cc0318 看到Address, overflow,往往是地址访问越界的错误。因此,遇到这个报错信息,说明数组的下标访问越界。 既然数组下标访问越界,则需要检查代码中与数组下标有关的判断语句、赋值语句或循 引索越界,做题时maxIndex = nums.size(); 应该是maxIndex = nums.size() - 1; ================================================================= ==30==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000000c at pc 0x000000401749 bp 0x7f
当j = size -1时,nums[j + 1]将超出数组nums的下标。 因此,将此段代码改为:
for (int j = i + 1; j < size; j++) { nums[j - 1] = nums[j]; 1. SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior 对数组进行操作时,一定要注意数组的可索引范围,保证数组不发生越界。在 Leetcode 中数组越界会给出如下几种报错信息: 1. AddressSanitizer: heap-buffer-overflow on address 报错信息: ==42==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000032 即if(p == 0||data[p-1]!= now),这样检查到p==0后就不会执行后面的data[p-1],这是因为||是逻辑上的或,前面的语句符合了就不会继续判断了。在力扣执行 s = "){"情况时,循环代码中if(data[p-1]!= now || p ==0)会先判断data[p-1],此时由于p==0,p-1必然造成数组越界从而导致报错,在这里,只需要将两个判断条件替换一下位置即可。这种时候在自己编译器上不一定能检查得出问题,对于力扣来说,这种情况大概率就是。 AddressSanitizer(ASan)是一个快速的内存错误检测工具。它非常快,只拖慢程序两倍左右。可以看到上述代码中,为了易读性,我把程序特殊情况挨着列出来,忘记了顺序问题,应该就是内存泄漏问题,一般出现在数组越界访问之类的。同样会报错,因为也是顺序执行的。 一般情况下是数组越界访问或者数组的下标错误造成的。 今天刷题时遇到这个错误死活找不到原因,因为发现就是数组越界了。 while(f[i]&&i<n)i++;这种写法是错误的,最后i到n了会先访问f[i]引起错误。所以遇到这种循环判断的越界条件一定要放在最开头。 这种小错误都犯了,这题还是得经常刷一段时间不写都忘了。 https://stackoverflow.com/... 我们在刷LeetCode时,往往会出现这种报错信息: AddressSanitizer: heap-buffer-overflow on address 0x602000000040 at pc 0x000000406b5e bp 0x7ffc15cc0320 sp 0x7ffc15cc0318 看到Address, overflow,往往是地址访问越界的错误。因此,遇到这个报错信息,说明数组的下标访问越界。 既然数组下标访问越界,则需要检查代码中与数组下标有关的判断语句、赋值语句或循 引索越界,做题时maxIndex = nums.size(); 应该是maxIndex = nums.size() - 1; ================================================================= ==30==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000000c at pc 0x000000401749 bp 0x7f