704. 二分查找
Leetcode链接: 二分查找
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length-1;
while(left <= right){
int mid = (right-left)/2 + left;
if(nums[mid] > target){
right = mid -1;
}else if(nums[mid] < target){
left = mid + 1;
}else{
return mid;
}
}
return -1;
}
}
做题一开始的感觉就是需要定义while,我一开始就在考虑如果nums[]的长度为1的情况。这种情况left和right就会相等。target需要和这个数字对比,所以自然我的while loop里面就会包括left == right的情况。
后面就是mid的求法,大家都用(right-left)/2 + left,这里我思考了很久,因为正常求mid应该是(right+left)/2,上面的求法是为了防止overflow。我就在想那为什么不能(right/2.0+left/2.0)这样呢?最后使用(int)((right/2.0) + (left/2.0))也过了。
代码随想录里讲解了左闭右开,左闭右闭两种区间规则。我还是更喜欢左闭右闭的方法。因为我觉得和mid对比过了之后就不需要在把mid包括在接下来的对比里面了。
27. 移除元素
Leetcode链接: 移除元素
//暴力解法
class Solution {
public int removeElement(int[] nums, int val) {
int size= nums.length;
for (int i = 0; i < size; ++i) {
if (nums[i] == val) {
for (int j = i; j < size-1; ++j) {
nums[j] = nums[j+1];
}
i--;
size--;
}
}
return size;
}
}
//快慢双指针法
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int fast = 0; fast < nums.length; fast ++){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
}
太久没写leetcode的代码了,一开始写快慢指针的方法思考了很久快慢指针的逻辑。总是在想如何找到数组中的val然后swap到后面去。后来看了一下动画还是没转过弯来。最后看了代码才发现,这个做法是把所有不是val的element都覆盖到前面来。
977.有序数组的平方
Leetcode链接: 有序数组的平方
class Solution {
public int[] sortedSquares(int[] nums) {
int[] result = new int[nums.length];
int front = 0;
int end = nums.length-1;
int i = nums.length-1;
while(front <= end){
int a = nums[front]*nums[front];
int b = nums[end]*nums[end];
if(a > b){
result[i] = a;
front++;
}else{
result[i] = b;
end --;
}
i--;
}
return result;
}
}
这道题一开始也没头绪,只知道双指针能做,但是不知道该怎么做。后面看了一眼双指针的动画,就马上懂了。一个指针在前一个指针在后,往中间遍历。然后比较两个指针里谁大就先移动。然后把更大的数组塞到array的最后一位。有点像merge sort后半部分的把分开的array合起来的步骤。
今日收获
复习了binary search,和双指针。对binary search和写法有了更多的理解。双指针还是很看思路的,有时候就算知道要使用双指针也不知道该怎么用。
记录一下自己的学习时长:
- leetcode:2h
- 博客:0.5h