今天在做LeetCode27题(https://leetcode.cn/problems/remove-element/)时发现了一个问题,我自己的解法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
public class LC27RemoveElement { public static int removeElement(int[] nums, int val) { int[] newNums = new int[nums.length]; int count = 0,j=0; for (int i = 0; i < nums.length; i++) { if (nums[i] == val) { count++; continue; } newNums[j]=nums[i]; j++; } nums = newNums;
return nums.length-count; }
public static void main(String[] args) { int[] nums = {3,2,2,3}; int lg = removeElement(nums, 3); System.out.println(lg); System.out.println("------------"); for (int i = 0; i < nums.length; i++) { System.out.println(nums[i]); } } }
|
以上代码的打印结果是[3,2,2,3]而不是[2,2,0,0],没有通过debug发现原因。
查询资料(参考链接:java 值传递 数组传递 - The_PopCore - 博客园 (cnblogs.com))发现原因如下:
以上代码中,虽然在removeElement
方法中将符合条件的元素替换为0,但是在main
方法中打印数组时,打印的仍然是原始的nums
数组,而没有打印替换后的nums
数组。这是因为Java中的数组是按值传递的,所以在removeElement
方法中修改nums
数组并不会影响main
方法中的nums
数组。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Test{ String str = new String("good"); char[] ch = {'a','b','c'}; int i = 10; public void change(String str,char ch,int i){ str = "test ok"; ch = 'g'; this.i = i+1; } public static void main(String[] args){ Test tt = new Test(); tt.change(tt.str,tt.ch[0],tt.i); System.out.println(tt.i); System.out.print(tt.str+" and "); System.out.println(tt.ch); } }
|
change()方法里的入参为char ch;
传递的是个char值的单个数组元素,此时ch=’g’;是不影响源数组元素的。
this.i = i+1;这里面等号左边的i是属性i,等号右边的i是局部变量(入参里的i);
此时i+1后赋值给属性的i,自然会改变属性i的值,同时17行,tt.i又是调用属性的i,输出的结果是:
顺带附上LeetCode27题我的解法:
题目:
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
1 2 3
| 输入:nums = [3,2,2,3], val = 3 输出:2, nums = [2,2] 解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
|
示例 2:
1 2 3
| 输入:nums = [0,1,2,2,3,0,4,2], val = 2 输出:5, nums = [0,1,3,0,4] 解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
|
这道题可以用双指针解法(快指针寻找新数组的元素 ,新数组就是不含有目标元素的数组,慢指针指向更新 新数组下标的位置):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package com.simonf.array;
public class LC27RemoveElement { public static int removeElement(int[] nums, int val) { int slowIndex = 0; int fastIndex ; for (fastIndex = 0; fastIndex < nums.length; fastIndex++) { if (nums[fastIndex] == val) { continue; } nums[slowIndex] = nums[fastIndex]; slowIndex++; } return slowIndex; }
public static void main(String[] args) { int[] nums = {3, 2, 2, 3}; int lg = removeElement(nums, 3); System.out.println(lg); System.out.println("------------"); for (int i = 0; i < nums.length; i++) { System.out.println(nums[i]); } }
}
|