LeetCode刷题计划---day4

卡码网 练习ACM模式 https://kamacoder.com/

1 数组理论基础

推荐链接:https://c.biancheng.net/view/dt3k3gp.html

数组下标都是从0开始的。且数组内存空间的地址是连续的。

正是因为数组的在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。

在这里插入图片描述

使用C++的话,要注意vector 和 array的区别,vector的底层实现是array,严格来讲vector是容器,不是数组。

数组的元素是不能删的,只能覆盖。在C++中二维数组是连续分布的。

#include <iostream>
using namespace std;

void test_arr(){
    int array[2][3] = {
        {0,1,2},
        {3,4,5}
    };
    cout<<&array[0][0]<<" "<<&array[0][1]<<" "<<&array[0][2]<<endl;
    cout<<&array[1][0]<<" "<<&array[1][1]<<" "<<&array[1][2]<<endl;
}


int main()
{
    test_arr();
    return 0;
}
0x7fff4913f570 0x7fff4913f574 0x7fff4913f578
0x7fff4913f57c 0x7fff4913f580 0x7fff4913f584

在这里插入图片描述
使用数组之前必须先定义数组。定义数组的语法如下:

类型 数组名[数组大小];

int num[10]; //正确

int length = 10;
char str[length]; //错误,length 是变量

const int length2 = 10;
char str[length2]; //正确

char arr[10 + 1]; // 正确
char arr2[length2 + 1]; // 正确

与变量的定义一样,数组也可以连续定义。例如:

int a[10], b[20], c[30];

数组的初始化

数组可以不初始化,但如果你不显式地对数组进行初始化,那么数组的元素值将取决于它们所在的内存位置的初始内容。这可能导致数组中的元素值是未知的或者随机的。
定义数组的同时,为数组中的元素提供初值,这就是所谓的初始化数组。

初始化数组有以下几种方式:

  • 直接初始化:int arr[5] = {1, 2, 3, 4, 5};
  • 指定部分元素初始化:int arr[5] = {1, 2};,其余元素将被初始化为0。
  • 不指定数组大小,根据初始化列表自动确定大小:int arr[] = {1, 2, 3, 4, 5};

注意,初始化数组指的是定义数组的同时为各个元素提供初值。对于先前定义的数组,不能采用初始化的方式指定各个元素的值,例如:
int num[5];
num = {10, 20, 30, 40, 50}; // 错误,不能这样赋值
这样写是错误的,对于先前定义的数组,只能分别为各个元素赋值。

  1. 同一数组中的所有元素必须是同一类型,尝试存储不同类型的元素会导致编译错误。
  2. 数组的长度在定义的时候必须确定,不能为变量。
  3. 定义后的数组,大小就不能改变了,所以在编程时,必须确保数组的大小符合需求。
  4. 操作数组中的元素,不能超出数组下标的范围。

在Python中,可以通过以下两种方式来定义和使用数组。

  1. 列表(List)的定义和使用:

    创建空列表:my_list = []

    添加元素到列表尾部:my_list.append(element)

    访问列表元素:value = my_list[index]

    修改列表元素:my_list[index] = new_value

    删除列表元素:del my_list[index]或者my_list.remove(element)

示例代码如下所示:

my_list=[]
my_list.append('a')
print(my_list)


print(my_list[0])

del my_list[0]
print(my_list)

my_list.append('b')
print(my_list)
my_list.remove(my_list[0])
  1. NumPy库提供了多维数组对象ndarray的支持,其定义和使用更加高效和功能丰富。需要先安装NumPy库才能使用该特性。

    导入NumPy库:import numpy as np

    创建ndarray对象:my_array = np.array([…])

    访问ndarray元素:value = my_array[index]

    切片操作:sliced_array = my_array[start🔚step]

    修改ndarray元素:直接通过索引进行赋值操作

    运算符重载:支持常见的数学运算、逐元素计算等操作

示例代码如下所示:

import numpy as np
 
# 创建ndarray对象
my_array = np.array([1, 2, 3, 4, 5])
 
# 访问ndarray元素
value = my_array[2]
print(value)  # 输出结果为 3
 
# 切片操作
sliced_array = my_array[1:4:2]
print(sliced_array)  # 输出结果为 [2 4]
 
# 修改ndarray元素
my_array[0] = 6
print(my_array)  # 输出结果为 [6 2 3 4 5]
 
# 运算符重载
result = my_array + 2
print(result)  # 输出结果为 [8 4 5 6 7]


17 二分查找

在这里插入图片描述
这道题目的前提是数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的,这些都是使用二分法的前提条件,当大家看到题目描述满足如上条件的时候,可要想一想是不是可以用二分法了。

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

这里两个注意的点,一个是vector取长度的时候用的是.size(),不是.length()
还有一个是有些自己不知道数组长度的时候,估计官方都给了,不用自己定义。

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left = 0
        right = len(nums) - 1
        while left <= right:
            middle = (left + right) // 2  # 计算中间位置
            if nums[middle] > target:
                right = middle - 1  # 更新右边界
            elif nums[middle] < target:
                left = middle + 1  # 更新左边界
            else:
                return middle  # 找到目标值,返回索引
        return -1  # 没有找到目标值,返回 -1


18 移除元素

在这里插入图片描述
这里要注意删除元素,是不能直接删除的,要覆盖,要把后面的元素移到前面来,然后用vector.size()的话,删除元素,它就会减少,但不是物理意义上的减少。存储空间是不会变的,只是删除的不处理了。

vector里面的erase的删除元素的接口,可是它是一个O(n)的操作,不是O(1)的。

class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        i = 0
        while i < len(nums):
            if nums[i] == val:
                nums.pop(i)  # 移除当前位置的元素
            else:
                i += 1  # 指针右移
        return len(nums)

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

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        nums.erase(std::remove(nums.begin(), nums.end(), val), nums.end());
        return nums.size();
    }
};


暴力的解法:

```cpp
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--;
                size--;
            }
        }
        return size;
    }
};
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        size = len(nums)
        i = 0
        while i < size:
            if nums[i] == val:
                for j in range(i+1, size):
                    nums[j-1] = nums[j]
                size -= 1
            else:
                i += 1

        return size

小心数组越界,初始化的时候,j=i+1,

双指针法:
双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

定义快慢指针

快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
慢指针:指向更新 新数组下标的位置

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow=0;
        int fast = 0;
        for (fast=0;fast<nums.size();fast++){
            if(nums[fast]!=val){
                nums[slow]=nums[fast];
                slow++;
            }
        }
        return slow;
    }
};
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        slow =0
        for fast in range(len(nums)):
            if nums[fast]!=val:
                nums[slow]=nums[fast]
                slow+=1
        return slow
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值