题目:
Given an array and a value, remove all instances of that value in place and return the new length.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
链接: http://leetcode.com/problems/remove-element/
一刷,做不到一遍bug free。19行比较有意思,因为left, right相对位置判断在值判断之前,当两个下标重合时,至少有一个是不符合第二个条件的,所以要判断当前值是否等于val。此解法从首尾各用一个下标,尾部的!=val直接填在前面,中间的不需要动。
另一种解法是从开头用2个下标的缺点是,除了最开始的一些元素,所有!=val的值都会被赋值一次。
3,2,2,3 val=3这个例子中,第一种解法只需要赋值1次,另外一种需要赋值2次。
1 class Solution(object): 2 def removeElement(self, nums, val): 3 """ 4 :type nums: List[int] 5 :type val: int 6 :rtype: int 7 """ 8 if not nums: 9 return 0 10 left = 0 11 right = len(nums) - 1 12 length = len(nums) 13 14 while left <= right: 15 while left < right and nums[left] != val: 16 left += 1 17 while right > left and nums[right] == val: 18 right -= 1 19 if left == right: 20 return left + 1 if nums[left] != val else left 21 nums[left] = nums[right] 22 left += 1 23 right -= 1 24 return left
2/11/2017, Java
错误:
第5行,b初始值应该是nums.length - 1
想到一个对待简单题下标的窍门,对每个下标的意义要清楚,不要仅仅是从前面的下标是f,从后面的下标是b。正确的方法是,f代表将要被比较可能被修改的值,b代表从后面开始未比较的而且不同于目标的值。
1 public class Solution { 2 public int removeElement(int[] nums, int val) { 3 if (nums == null) return 0; 4 int f = 0; 5 int b = nums.length - 1; 6 while (b >= 0 && nums[b] == val) b--; 7 if (b < 0) return 0; 8 9 while (f <= b) { 10 if (nums[f] == val) { 11 nums[f] = nums[b--]; 12 while (nums[b] == val) b--; 13 } 14 f++; 15 } 16 return f; 17 } 18 }