刷题DAY1_数组

刷题DAY1_数组

  • 数组理论基础
  • 二分查找(704)
  • 在排序数组中查找元素的第一个和最后一个位置 (34)
  • 注意事项和错误记录

数组理论基础

  1. 数组是存放在 连续内存空间 上的 相同类型数据 的集合。
  2. 数组下标都是从 0 开始的。
  3. 数组内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。严格来讲,数组的元素是不能删的,只能覆盖

二分查找(704)

def erfenfa(nums,target):  # python
    l,r = 0,len(nums)-1

    while (l < r):
        mid = (l + r) // 2
        if target < nums[mid]:
            r = mid - 1
        elif target > nums[mid]:
            l = mid + 1
        else:
            return mid
    return -1

if __name__ == "__main__":
    nums = [-1, 0, 3, 5, 9, 12]
    target = 6
    print(erfenfa(nums,target))
#include <iostream>   //C++
using namespace std;

int erfenfa(int nums[], int target,int n) {

	int l = 0;
	int r = n - 1; //c++中,如果将数组作为参数传递,则在函数中是无法获得数组的大小的
	while(l <= r){
		int mid = (l + r) / 2;
		if (nums[mid] < target) {
			l = mid + 1;
		}else if(nums[mid] > target) {
			r = mid - 1;
		}
		else {
			return mid;
		}
	}
	return -1;
}

int main() {
	int nums[6] = { -1, 0, 3, 5, 9, 12 };
	int target = 9;
	int n = sizeof(nums)/sizeof(nums[0]);

	cout << erfenfa(nums,target,n) << endl;
}

在排序数组中查找元素的第一个和最后一个位置 (34)

def erfenfa(nums,target): #python

    leftBoder = getLeftBorder(nums, target)
    rightBoder = getRightBorder(nums, target)
    # 情况一
    if leftBoder == -2 or rightBoder == -2: return [-1, -1]
    # 情况三
    if rightBoder - leftBoder > 1: return [leftBoder + 1, rightBoder - 1]
    # 情况二
    return [-1, -1]


def getRightBorder(nums, target):
    left, right = 0, len(nums) - 1
    rightBoder = -2  # 记录一下rightBorder没有被赋值的情况
    while left <= right:
        middle = left + (right - left) // 2
        if nums[middle] > target:
            right = middle - 1
        else:  # 寻找右边界,nums[middle] == target的时候更新left
            left = middle + 1
            rightBoder = left

    return rightBoder


def getLeftBorder(nums, target):
    left, right = 0, len(nums) - 1
    leftBoder = -2  # 记录一下leftBorder没有被赋值的情况
    while left <= right:
        middle = left + (right - left) // 2
        if nums[middle] >= target:  # 寻找左边界,nums[middle] == target的时候更新right
            right = middle - 1
            leftBoder = right
        else:
            left = middle + 1
    return leftBoder

if __name__ == "__main__":
    nums = [-1, 0, 3, 5, 9]
    target = 5
    print(erfenfa(nums, target))
#include <iostream>      //C++
using namespace std;

int getRightBorder(int nums[], int target, int n);//函数声明
int getLeftBorder(int nums[], int target, int n);

int erfenfa(int nums[], int target,int n) {

	int rightBorder = getRightBorder(nums, target, n);
	int leftBorder = getLeftBorder(nums, target, n);

	// 情况一
	if (leftBorder == -2 || rightBorder == -2) return -1,-1;
	// 情况三
	if (rightBorder - leftBorder > 1) return leftBorder + 1, rightBorder - 1;
	// 情况二
	return -1, -1;

}

int getRightBorder(int nums[], int target,int n) {
	int left = 0;
	int right = n - 1;
	int rightBorder = -2; // 记录一下rightBorder没有被赋值的情况
	while (left <= right) { // 当left==right,区间[left, right]依然有效
		int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
		if (nums[middle] > target) {
			right = middle - 1; // target 在左区间,所以[left, middle - 1]
		}
		else { // 当nums[middle] == target的时候,更新left,这样才能得到target的右边界
			left = middle + 1;
			rightBorder = left;
		}
	}
	return rightBorder;
}

int getLeftBorder(int nums[], int target, int n) {
	int left = 0;
	int right = n - 1;
	int leftBorder = -2; // 记录一下leftBorder没有被赋值的情况
	while (left <= right) {
		int middle = left + ((right - left) / 2);
		if (nums[middle] >= target) { // 寻找左边界,就要在nums[middle] == target的时候更新right
			right = middle - 1;
			leftBorder = right;
		}
		else {
			left = middle + 1;
		}
	}
	return leftBorder;
}

int main() {
	int nums[6] = { -1, 0, 3, 5, 9, 12 };
	int target = 9;
	int n = sizeof(nums)/sizeof(nums[0]);
	cout << erfenfa(nums, target, n) << endl;	
}

注意事项和错误记录

  1. 注意在写代码过程中区间的 左闭右开和左闭右闭,本次代码python部分是__左闭右开__,C++是 左闭右闭
  2. C++中,如果将数组作为参数传递,则在函数中是无法获得数组的大小的。
  3. C++中没有直接得到数组大小的库函数,本文采用:sizeof(nums)/sizeof(nums[0]) 求得数组大小。
  4. C++需要函数生命的几种情况如下:
    (1) 函数定义在main函数后面:如果函数定义在main函数后面,那么在调用该函数之前需要在main函数上方声明该函数。
    (2) 函数定义在另一个文件中:如果函数定义在另一个文件中,那么需要在main函数上方声明该函数,以便编译器能够正确地编译和链接该函数。
    (3) 函数需要传递参数:如果函数需要传递参数,那么需要在main函数上方声明该函数,并指定参数的类型和数量,以便编译器能够正确地编译和链接该函数。
  5. 二分查找前提是数组中 无重复 元素。
  6. 在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则:left 永远小于等于right
  7. 遇到 平方根、次方根 的问题也可以用到二分查找的方法,相关题目 如力扣69.x 的平方根,367.有效的完全平方数。

个人刷题记录整理,欢迎随时纠错和讨论!

你可能感兴趣的:(python,c++,力扣)