[leetcode]初级算法__数组 题解记录(自用,持续更新。。。)

leetcode初级算法网址

https://leetcode-cn.com/leetbook/detail/top-interview-questions-easy/

1、删除排序数组中的重复项

解题思路:

本题使用了双指针的技巧。个人理解,其实可以看成新生成了一个数组,只是为了节省空间,就使用了双指针进行原地修改。
值得注意的是,本题给了很多的限定:

  1. 数组是升序的
  2. 返回值是数组长度,这也在暗示原地修改
    其次,注意下特殊情况:无需查重的(数组为空数组或者只有一个元素),直接返回numsSize即可。
    双指针思想在本题中的实际应用:
    我们可以考虑这个问题:输入一串数字进行存储,重复的除外。输入的这一串数字,也就是数组nums[],用变量i遍历读取,遍历完了的地址空间,因为不要求保留原始数据,所以都是可用的。如图,遍历到nums[2]的时候,nums[2]之前的地址位其实都是可用的,都已经读取过了,里边的值没必要管。
    利用这一片地址空间(原地),来存储结果。此时,存储结果的就是指针j来标记。因此,指针j初始化为0,也没有从0开始遍历数组的必要,有重复发生的话,至少得是两个元素嘛,指针i就初始化为1。
    在这里插入图片描述

接下来,用变量j指向的地址空间存储最终结果,每次遇到非重复元素,就需要记录下来,详见题解代码。
错误代码

//输入[1,1,2],输出[1]
int removeDuplicates(int* nums, int numsSize){
    int i = 0,j = 0;
    if(numsSize == 0)
    return 0;
    for(; i < numsSize-1; i++)
    {
        //nums[j] = nums[i];
        if(nums[i] != nums[j])
        {
            j = j + 1;
            nums[j] = nums[i];
        }
    }
    return j + 1;
}

题解:

int removeDuplicates(int* nums, int numsSize)
{
    if(numsSize < 2)
    return numsSize;
    int i = 1;
    int j = 0;
    for(; i < numsSize; i++)
    {
        if(nums[i] != nums[j])
        {
            nums[++j] = nums[i];
        }
    }
    return j + 1;
}

特别注意:边界条件设置

2、买卖股票的最佳时机Ⅱ

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/submissions/

解题思路

类似贪心的思想,贪的就是只要有上涨的,就出售,每次出售利润的总和就是最终利润。这贪的局部最优解应该也是整体最优解,毕竟若是类似1,3,9的情况,每次上涨就出售,和涨的最多再出售结果都是能赚8,怎么说呢,9-1 = (3-1)+ (9-3)嘛,类似于化学里催化剂的作用嘛,断键需要的总能量那么多,加催化剂其实也一样。
错误代码:

/*
默认第一天的就是最小的
*/
int maxProfit(int* prices, int pricesSize){
//涨了就出售
    if(pricesSize < 2)
    return 0;
    int i = 1;
    int profit = 0;
    int j = 0;
    for(;i < pricesSize; i++)
    {
        if(prices[i] > prices[j])
        {
            profit = profit + prices[i] - prices[j];
            j = i;
        }
    }
    return profit;
}

在这里插入图片描述

题解

int maxProfit(int* prices, int pricesSize){
//涨了就出售
    if(pricesSize < 2)
    return 0;
    int i = 1;
    int profit = 0;
    int j = 0;
    for(;i < pricesSize; i++)
    {
        if(prices[i] > prices[j])
        {
            profit = profit + prices[i] - prices[j];
            j = i;
        }
        else
        j = i;
    }
    return profit;
}
/*j = i可以合并一下,好看~~*/

3、旋转数组

https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2skh7/

解题思路

方法1:使用一个数组暂存需要交换的值。
本题是指就是后k个数放到数组开始,其余的依次往后移。值得注意的是:当numsSize < k时,代表数组右移k-numsSize个数,类似于补码的思想。

//未考虑numsSize < k的正确处理方式
void rotate(int* nums, int numsSize, int k)
{
    if(numsSize < 2 || numsSize <= k)
    return;
    int temp[numsSize - k];
    int i = numsSize - k;
    int j = 0;
    for(;i < numsSize; i++)
    {
        temp[j] = nums[i];
        j++;
    }
    for(i = numsSize - k -1; i >= 0; i--)
    {
        nums[i + k] = nums[i]; 
    }
    for(i = 0; i < k; i++)
    {
        nums[i] = temp[i];
    }
    return;
}
//修改后仍是numssize < k时,runtime不通过
void rotate(int* nums, int numsSize, int k)
{
    if(numsSize < 2)
    return;
    if(numsSize <= k)
    {
        int i = 0;
        int temp;
        for(; i < numsSize / 2; i++)
        {
            temp = nums[i];
            nums[i] = nums[numsSize - i - 1];
            nums[numsSize - i - 1] = temp;
        }
        return;
    }
    else
    {
    int temp[numsSize - k];
    int i = numsSize - k;
    int j = 0;
    for(;i < numsSize; i++)
    {
        temp[j] = nums[i];
        j++;
    }
    for(i = numsSize - k -1; i >= 0; i--)
    {
        nums[i + k] = nums[i]; 
    }
    for(i = 0; i < k; i++)
    {
        nums[i] = temp[i];
    }
    return;
    }
}

在这里插入图片描述

//用例为[1,2,3],2时,出现temp[1],长度为1的数组,而循环体中有temp[0]
void rotate(int* nums, int numsSize, int k)
{
    if(numsSize == k)
        return;
    if(numsSize < k)
    {
        int i = 0;
        int temp[numsSize];
        for(; i < numsSize; i++)
        {
            temp[i] = nums[numsSize - i - 1];
        }
        for(i = 0; i < numsSize; i++)
        {
            nums[i] = temp[i];
        }
        return;
    }
    else
    {
    int temp[numsSize - k];
    int i = numsSize - k;
    int j = 0;
    for(;i < numsSize; i++)
    {
        temp[j] = nums[i];
        j++;
    }
    for(i = numsSize - k -1; i >= 0; i--)
    {
        nums[i + k] = nums[i]; 
    }
    for(i = 0; i < k; i++)
    {
        nums[i] = temp[i];
    }
    return;
    }
}

在这里插入图片描述

题解

其实就相当于前(numsize-k)个和后k个换了个位置。
在这里插入图片描述

void rotate(int* nums, int numsSize, int k) 
{
    int temp[numsSize];
    if(k > numsSize)
    k = k % numsSize;
    for (int i = 0; i < numsSize; i++) 
    {
        if(i < k)
        temp[i] = nums[numsSize -k + i];
        else
        temp[i] = nums[i - k];
    }
    for (int i = 0; i < numsSize; i++) {
        nums[i] = temp[i];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值