LeetCode官网题目地址:力扣
Java实现代码:
package array; import java.util.ArrayList; /** * @ClassName LeetCode 27.移除元素 * @Description https://leetcode.cn/problems/remove-element/ * @Author Jiangnan Cui * @Date 2022/10/23 19:58 * @Version 1.0 */ public class LeetCode27 { /** * @MethodName removeElement * @Description 方法1:新建一个ArrayList,使用额外的空间来存储元素 * 时间复杂度:O(n),其中,n为数组长度 * 空间复杂度:O(n) * 但不满足题目要求 * @param: nums 目标数组 * @param: val 移除元素值 * @return: int 返回不等于val的数组元素个数 * @Author Jiangnan Cui * @Date 23:02 2022/10/24 */ public int removeElement(int[] nums, int val) { // 用ArrayList来保存满足要求的数组元素 ArrayList<Integer> list = new ArrayList<Integer>(); // 遍历数组 for (int i = 0; i < nums.length; i++) { // 不等于val时 if(nums[i] != val){ // 存入result list.add(nums[i]); } // 等于val时,不做任何处理 } // 遍历完成后,list的大小即为不等于val元素值的数组的长度 // 注意:此处只为满足题目要求,即所得结果长度对应的原数组元素满足要求,不然测试时输出结果数组不对,不涉及原数组时不用考虑 // 对原数组对应位置元素进行替换 for (int i = 0; i < list.size(); i++) { nums[i] = list.get(i); } // 返回有效元素长度 return list.size(); } /** * @MethodName removeElement2 * @Description 方法2:原地移除元素,通过复制元素实现 * 时间复杂度:O(n),其中,n为数组长度 * 空间复杂度:O(1),其中,需要常数个变量空间 * 满足题目要求 * @param: nums 目标数组 * @param: val 移除元素值 * @return: int 返回不等于val的数组元素个数 * @Author Jiangnan Cui * @Date 23:02 2022/10/24 */ public int removeElement2(int[] nums, int val) { // 用作记录不等于val时的下标索引 int index = 0; // 遍历数组 for (int i = 0; i < nums.length; i++) { // 不等于val时 if(nums[i] != val){ // 放入数组指定的index位置,同时index加1右移 nums[index++] = nums[i]; } // 等于val时,不做任何处理 } // 遍历完成后,index的大小即为不等于val元素值的数组的长度 return index; } /** * @MethodName removeElement3 * @Description 方法3:对方法2进行优化,避免两个元素相同时的重复赋值操作 * 时间复杂度:O(n),其中,n为数组长度 * 空间复杂度:O(1),其中,需要常数个变量空间 * 满足题目要求 * @param: nums 目标数组 * @param: val 移除元素值 * @return: int 返回不等于val的数组元素个数 * @Author Jiangnan Cui * @Date 23:02 2022/10/24 */ public int removeElement3(int[] nums, int val) { // 用作记录不等于val时的下标索引 int index = 0; // 遍历数组 for (int i = 0; i < nums.length; i++) { // 不等于val时 if(nums[i] != val){ // 判断两个位置是否相同,相同时不做处理,但index要加1,向右移动 if(i == index){ index++; }else{// 两个位置不相同时。放入数组指定的index位置,同时index加1右移 nums[index++] = nums[i]; } } // 等于val时,不做任何处理 } // 遍历完成后,index的大小即为不等于val元素值的数组的长度 return index; } /** * @MethodName removeElement4 * @Description 方法4:双指针法,通过while循环实现 * 时间复杂度:O(n),其中,n为数组长度 * 空间复杂度:O(1),其中,需要常数个变量空间 * 满足题目要求 * @param: nums 目标数组 * @param: val 移除元素值 * @return: int 返回不等于val的数组元素个数 * @Author Jiangnan Cui * @Date 23:02 2022/10/24 */ public int removeElement4(int[] nums, int val) { // 用作记录不等于val时的下标索引 int i = 0; // 用来指定边界 int right = nums.length; // 循环条件 while(i < right){ // 当数组中元素值等于待移除元素值时 if(nums[i] == val){ // 将右侧元素放到要移除元素的位置上进行元素替换 nums[i] = nums[right - 1]; // 此时右侧的元素已经替换掉左侧待移除的元素了,right指针左移,改变right指针位置 right--; // 接下来判断交换的元素是否满足条件,即回到while循环条件判断处 }else{ // 不相等时,i加1右移,right不变 i++; } } // 当i==right时,退出循环,此时i的大小即为不等于val时元素的个数 return i; } /** * @MethodName removeElement5 * @Description 方法5:对方法4进行进行优化,相同元素时不交换 * 时间复杂度:O(n),其中,n为数组长度 * 空间复杂度:O(1),其中,需要常数个变量空间 * 满足题目要求 * @param: nums 目标数组 * @param: val 移除元素值 * @return: int 返回不等于val的数组元素个数 * @Author Jiangnan Cui * @Date 23:02 2022/10/24 */ public int removeElement5(int[] nums, int val) { // 用作记录不等于val时的下标索引 int i = 0; // 用来指定边界 int right = nums.length; // 循环条件 while(i < right){ // 当数组中元素值等于待移除元素值时 if(nums[i] == val){ // 将右侧元素放到要移除元素的位置上进行元素替换 // 先判断右侧元素是否与当前元素相等,不相等时才交换元素,同时right减1左移 if(nums[i] != nums[right - 1]){ nums[i] = nums[right - 1]; } // 相等时,不必交换,只需要right减1左移即可 right--; // 此时右侧的元素已经替换掉左侧待移除的元素了,接下来判断交换的元素是否满足条件,即回到while循环条件判断处 }else{ // 不相等时,i加1右移,right不变 i++; } } // 当i==right时,退出循环,此时i的大小即为不等于val时元素的个数 return i; } /** * @MethodName removeElement6 * @Description 方法6:对方法5的边界条件进行改变,测试使用 * 时间复杂度:O(n),其中,n为数组长度 * 空间复杂度:O(1),其中,需要常数个变量空间 * 满足题目要求 * @param: nums 目标数组 * @param: val 移除元素值 * @return: int 返回不等于val的数组元素个数 * @Author Jiangnan Cui * @Date 23:02 2022/10/24 */ public int removeElement6(int[] nums, int val) { // 用作记录不等于val时的下标索引 int i = 0; // 用来指定边界,此处改为数组最右侧索引下标 int right = nums.length - 1; // 循环条件 while(i <= right){ // 当数组中元素值等于待移除元素值时 if(nums[i] == val){ // 将右侧元素放到要移除元素的位置上进行元素替换 // 先判断右侧元素是否与当前元素相等,不相等时才交换元素,同时right减1左移 if(nums[i] != nums[right]){ nums[i] = nums[right]; } // 相等时,不必交换,只需要right减1左移即可 right--; // 此时右侧的元素已经替换掉左侧待移除的元素了,接下来判断交换的元素是否满足条件,即回到while循环条件判断处 }else{ // 不相等时,i加1右移,right不变 i++; } } // 当i>right时,退出循环,此时i的大小即为不等于val时元素的个数 return i; } public static void main(String[] args) { int[] nums = new int[]{3,2,2,3}; int val = 3; int i = new LeetCode27().removeElement(nums, val); System.out.println("i = " + i); int[] nums2 = new int[]{3,2,2,3}; int val2 = 3; int i2 = new LeetCode27().removeElement2(nums2, val2); System.out.println("i2 = " + i2); int[] nums3 = new int[]{3,2,2,3}; int val3 = 3; int i3 = new LeetCode27().removeElement3(nums3, val3); System.out.println("i3 = " + i3); int[] nums4 = new int[]{3,2,2,3}; int val4 = 3; int i4 = new LeetCode27().removeElement4(nums4, val4); System.out.println("i4 = " + i4); int[] nums5 = new int[]{3,2,2,3}; int val5 = 3; int i5 = new LeetCode27().removeElement5(nums5, val5); System.out.println("i5 = " + i5); int[] nums6 = new int[]{0,1,2,2,3,0,4,2}; int val6 = 2; int i6 = new LeetCode27().removeElement(nums6, val6); System.out.println("i6 = " + i6); int[] nums7 = new int[]{0,1,2,2,3,0,4,2}; int val7 = 2; int i7 = new LeetCode27().removeElement2(nums7, val7); System.out.println("i7 = " + i7); int[] nums8 = new int[]{0,1,2,2,3,0,4,2}; int val8 = 2; int i8 = new LeetCode27().removeElement3(nums8, val8); System.out.println("i8 = " + i8); int[] nums9 = new int[]{0,1,2,2,3,0,4,2}; int val9 = 2; int i9 = new LeetCode27().removeElement4(nums9, val9); System.out.println("i9 = " + i9); int[] nums10 = new int[]{0,1,2,2,3,0,4,2}; int val10 = 2; int i10 = new LeetCode27().removeElement5(nums10, val10); System.out.println("i10 = " + i10); int[] nums101 = new int[]{3,2,2,3}; int val101 = 2; int i101 = new LeetCode27().removeElement6(nums101, val101); System.out.println("i101 = " + i101); int[] nums102 = new int[]{0,1,2,2,3,0,4,2}; int val102 = 2; int i102 = new LeetCode27().removeElement6(nums102, val102); System.out.println("i102 = " + i102); } }
输出结果:
i = 2 i2 = 2 i3 = 2 i4 = 2 i5 = 2 i6 = 5 i7 = 5 i8 = 5 i9 = 5 i10 = 5 i101 = 2 i102 = 5