# 代码随想录算法训练营第一天| 704. Binary Search、27. Remove Element

TODO: 
27 remove element 解析

[Data Structure] Array

Goal: 了解一下数组基础,以及数组的内存空间地址,数组也没那么简单

704. Binary Search


Binary Search (Data Structure and Algorithm)

  1. 使用二分法的前提条件
    (a) an array of integers nums which is sorted in ascending order.
    (b) All the integers in nums are unique.
  2. 二分法种类(依照边界条件区分):
    (a) [left, right] 左闭右闭:while (left <= right)
    (b) [left, right) 左闭右开:while (left < right)

### Intuition 题目提到:(1) ascending sorted order, (2) all the integers in nums are unique。由题可知: Binary Search。下一步思考是哪一种 Binary Search? `[left, right]` or `[left, right)`?

Approach 1: [left, right]左闭右闭

  • Time Complexity: O(log n)
    nums 每次被切一半。在 worst-case 情况下,对半切直到该范围没有 element,这将花费 O(log n)
  • Space Complexity: O(1)
    因为只需要 3 个 index:left, mid, right
public int search(int[] nums, int target) {
	// edge case
 	if (target < nums[0] || target > nums[nums.length - 1]) {
    	return -1;
    }
    
    // 如何实作 binary search ?? 找 mid 再移动?
    int left = 0;
    int right = nums.length - 1;
    while (left <= right) {
        int mid = (right - left) / 2 + left;
        if (nums[mid] == target) {
            return mid; // found target value
        } else if (nums[mid] > target) { // Q: 搞不清楚怎么换 boundary...需再了解
            right = mid - 1; // target 在左区间,在[left, middle - 1] 中
        } else {
            left = mid + 1;  // target 在右区间,在[middle + 1, right] 中
        }
    }
    return -1; // not found target value
}

没有思考到的点:

  • edge case 改写:
// avoid (1) target < nums[0] || (2) target > nums[nums.length - 1] 
        if (target < nums[0] || target > nums[nums.length - 1]) {
            return -1;
        }
  • Why don’t use int mid = (right + left) / 2;? it might cause overflow
    Example: int range = 21 亿
    • int left = 21 亿, int right = 22 亿 => (left + right) / 2 = 21.5 亿 (overflow)
    • Solution: int mid = left + (right - left) /2;
延伸思索
  1. How to identify [left, right) and [left, right] in the question?
  2. 容易混淆的 while左右区间
    (1)while (left < right) || while (left <= right)
    a. 左闭右闭 [left, right]while (left <= right) ,举例:[1, 1] 合法区间,因为能取到 rigth 值。
    b. 左闭右开 [left, right)while (left < right) ,举例:[1, 1) 不合法区间,所以是 <
    (2) else if (nums[mid] > target) { right = mid - 1 || right = mid } ?
    根据区间定义,来给 right 赋值:right = mid - 1 || right = mid
    a. 左闭右闭[left, right]while (left <= right):在此次的搜寻已发现: nums[mid] != target value,所以下一次搜索要剔除 nums[mid]
    mid index,所以下一个区间是 [left, mid - 1]
    b. 左闭右开 [left, right)while (left < right)
if (nums[mid] > target) { // [ target, ..,  mid] => target 位在左区间
    right = mid; // 因为左闭右开,所以 [left, mid) => 直接 right = mid 即可。
} else if ( nums[mid] < target) { // [mid, .., target] => target 位在右区间
   left = mid + 1 // 因为在此次搜索中已发现 nums[mid] != target val 所以下一次搜索不包含 nums[mid],要剔除,因此 left = mid + 1。
}
  1. right = nums.length || nums.length - 1?
    a. 左闭右闭 [left, right]while (left <= right)right = nums.length - 1;
    b. 左闭右开 [left, right)while (left < right)right = nums.length;
    困惑: why 左闭右开 [left, right)while (left < right)right = nums.length;?

27. Remove Element

Intuition

Approach 1: Brute Force

class Solution {
    public int removeElement(int[] nums, int val) { 
        int size = nums.length;
        for (int i = 0 ; i < size ; i++) {
            // remove the element which is euqal to val.
            if (nums[i] == val) { 
                for (int j = i + 1 ; j < size ; j++) {
                    // move all element forward one pos
                    nums[j-1] = nums[j];
                }
            }
            i--; //  i move forward 1 pos because elements behind i move forward 1 pos
            size--; // array size - 1 beacuse remove 1 element that value is equal to val.
            }    
        }
    }
}

Approach 2: Two-Pointers

class Solution {
    public int removeElement(int[] nums, int val) { 
        int slow = 0;
        for (int fast = 0 ; fastIdx < nums.length ; fast++) {
            if (nums[fast] != val) {
                nums[slow] = nums[fast];
                slow++;
            }
        }
        return slow;
    }
}

Related Questions:

  1. Binary Search
  • Easy - 35. Search Insert Position
  • Easy - 34. Find First and Last Position of Element in Sorted Array
  • Easy - 69. Sqrt(x)
  • Easy - 367. Valid Perfect Square
  1. Remove element
  • Easy - 26. Remove Duplicates from Sorted Array
  • Easy - 283. Move Zeroes
  • Easy - 844. Backspace String Compare
  • Easy - 977. Squares of a Sorted Array
  • 25
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值