代码随想录刷题题Day1

刷题的第一天,希望自己能够不断坚持下去,迎来蜕变。
刷题语言:C++ / Python

Day1 任务

数组理论基础
704. 二分查找
27. 移除元素

1 数组理论基础

数组:存放连续内存空间上的相同类型数据的集合
Tip:(1) 数组下标都是从0开始 (2) 数组内存空间的地址是连续的
因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址

数组的元素不能删,只能覆盖
在C++中,二维数组在地址空间上也是连续的

2 二分查找

我熟悉了根据左闭右开,左闭右闭两种区间规则写出来的二分法
前提:
(1)数组为有序数组
(2)强调数组无重复元素 (一旦有重复元素,使用二分返回的元素下标可能不是唯一的)

区间的定义:不变量。
循环不变量:在while寻找每一次边界的处理都要坚持根据区间的定义来操作

代码随想录刷题题Day1_第1张图片
(1) [ l e f t , r i g h t ] [left, right] [left,right]左闭右闭
C++:

class Solution {
public:
    int search(vector<int>& nums, int target) {
		int left = 0;
		int right = nums.size() - 1;
		while (left <= right)
		{
			int mid = (left + right) / 2;
			if (nums[mid] > target) // [left, mid - 1]
			{
				right = mid - 1;
			}
			else if (nums[mid] < target) // [mid + 1, right]
			{
				left = mid + 1;
			}
			else
			{
				return mid;
			}
		}
		return -1;
    }
};

Python:

class Solution(object):
    def search(self, nums, target):
        left = 0
        right = len(nums) - 1
        while (left <= right):
            mid = (left + right) // 2
            if (nums[mid] > target):
                right = mid - 1
            elif (nums[mid] < target):
                left = mid + 1
            else:
                return mid
        return -1   

(2) [ l e f t , r i g h t ) [left, right) [left,right) 左闭右开
C++:

class Solution {
public:
    int search(vector<int>& nums, int target) {
		int left = 0;
		int right = nums.size();
		while (left < right) // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
		{
			int mid = (left + right) / 2;
			if (nums[mid] > target) // [left, mid)
			{
				right = mid;
			}
			else if (nums[mid] < target) // [mid + 1, right)
			{
				left = mid + 1;
			}
			else
			{
				return mid;
			}
		}
		return -1;
    }
};

Python:

class Solution(object):
    def search(self, nums, target):
        left = 0
        right = len(nums)
        while (left < right):
            mid = (left + right) // 2
            if (nums[mid] > target):
                right = mid
            elif (nums[mid] < target):
                left = mid + 1
            else:
                return mid
        return -1

3 移除元素

掌握了暴力解法和双指针(快慢指针)的解法
代码随想录刷题题Day1_第2张图片
(1)暴力解法
第一个for循环遍历数组元素
第二个for循环更新数组,发现元素,集体向前移动

时间复杂度: O ( n 2 ) O(n^2) O(n2)
C++:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
		int size = nums.size();
		for (int i = 0; i < size; i++)
		{
			if (nums[i] == val)
			{// 发现需要移除的元素,将数组集体向前移动一位
				for (int j = i + 1; j < size; j++)
				{
					nums[j - 1] = nums[j];
				}
				i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
				size--;// 数组的大小-1
			}
		}
		return size;
    }
};

Python:

class Solution(object):
    def removeElement(self, nums, val):
        i = 0
        size = len(nums)
        while i < size:
            if nums[i] == val:
                for j in range(i+1, size):
                    nums[j-1] = nums[j]
                i-=1
                size-=1
            i += 1
        return size

(2)双指针法
快慢指针:通过一个快指针和慢指针在一个for循环下完成两个for循环的工作
快指针:新数组元素
慢指针:更新新数组下标的位置

伪代码

slow = 0;
for (fast = 0; fast < nums.size; fast++)
{
	if (nums[fast] != val) # fast 寻找新数组元素
		nums[slow++] = nums[fast];# slow更新新数组下标的位置
}

时间复杂度: O ( n ) O(n) O(n)
空间复杂度: O ( 1 ) O(1) O(1)

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow = 0;
        for (int fast = 0; fast < nums.size(); fast++)
        {
            if (nums[fast] != val)
            {
                nums[slow++] = nums[fast];
            }
        }
        return slow;
    }
};

Python:

class Solution(object):
    def removeElement(self, nums, val):
        slow = 0  # 慢指针
        fast = 0  # 快指针
        size = len(nums)
        while fast < size:# 不加等于是因为,a = size 时,nums[a] 会越界
            # slow 用来收集不等于 val 的值,如果 fast 对应值不等于 val,则把它与 slow 替换
            if nums[fast] != val:
                nums[slow] = nums[fast]
                slow += 1
            fast += 1
        return slow

鼓励坚持一天的自己

你可能感兴趣的:(代码随想录刷题,c++,数据结构)