自己的解法是这样的,超出了时间限制,现在觉得应该是在mid的计算中出了问题。
然后在mid的转换中没有right减去1或者left加上1。这两点的问题。
自己很习惯的方式是左闭合加上右闭合。可以省去很多对于临界值忘记考虑的麻烦。
超时代码贴出:
public int search(int[] nums, int target) { int len = nums.length; int left = 0; int right = len - 1; while (left < right) { int mid = (left + right) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid; } else if (nums[mid] > target) { right = mid; } } return -1; }
改进后的代码。代码是一个很抠细节的东西。
public static int search(int[] nums, int target) { int len = nums.length; int left = 0; int right = len - 1; //左闭合右闭合 while (left <= right) { int mid = left + (right - left) / 2;//防止想加以后溢出(left + right) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid + 1;//挪一位mid; } else if (nums[mid] > target) { right = mid - 1;//挪一位mid; } } return -1; }
这题真的是小题大做了,改了很多版本以后,边界问题得不到解决。最终觉得不太适合左右端点往中间移动的双指针这样的模式。适合快慢双指针。
public int removeElement(int[] nums, int val) { int left = 0; int len = nums.length; int right = len - 1; int count = 0; // 需要找的最多次数就是len次,len从前往后找, // 找到以后和right对调,对调以后right左移动一个单位 // 有一个极限情况,左边不等于val时,右边刚好等于val // 左边发现和val相等的元素时,元素是交换 while (left <= right) { if (nums[left] != val) { left++; if (nums[right] == val) { right--; count++; } } else { count++; //交换 int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; left++; right--; } } return count; }
快慢双指针的方法:
这里的++i和i++结合运用的非常巧妙,感觉跟我这个二分法的mid没有前移一位或者后移一位我在这里犯了同样的错误。i是快指针,快指针找到目标值以后直接赋值给慢指针的位置。
但是我考虑到一个慢指针原来的值被丢弃的问题。
后来想到了,因为慢指针所到之处,快指针肯定都经过了,所以,需要的值肯定都已经存好了,所以不会有这个问题。也不需要追加一个数组作为内存开销。
public static int removeElement(int[] nums, int val) { int size = nums.length; int cnt = 0; for(int i = 0;i < size; ++i){ if(nums[i] != val){ nums[cnt++] = nums[i]; } } return cnt; }
标签:right,nums,int,随想录,mid,len,移除,打卡,left From: https://www.cnblogs.com/daihao547/p/18206040