Leecode刷题日记Day1(数组)

本文介绍了如何用C语言实现一系列与数组操作相关的算法,包括合并有序数组、移除重复元素、查找多数元素、股票买卖问题和最大子数组和。作者强调了快慢指针技巧在这些问题中的应用,以及不同的解决方案和优化思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.合并两个有序数组 (merge)

void switch_num(int*num, int pos1, int pos2){
    int a = 0;
    a = num[pos1];
    num[pos1] = num[pos2];
    num[pos2] = a;
    return;
}
int removeElement(int* nums, int numsSize, int val) {
    //no need to consider the order
    //switch all val to the rear
    int first_Val = numsSize-1;
    int pos = numsSize-1;
    while(pos>=0){
        if(nums[pos] == val){
            switch_num(nums, first_Val, pos);
            pos--;
            first_Val--;
        }
        else{
            pos--;
        }
    }
    return first_Val+1;
}

我的思路

经典做法,不用多说,但是要记住,看到类似的算法要马上回忆起来。

2. 移除元素

我的思路

就地移除,办法是移到后面藏起来,从数组末尾开始有奇效,目前不知道为什么。

双指针法,一个用来遍历,一个用来确定放置位置。

我的算法

void switch_num(int*num, int pos1, int pos2){
    int a = 0;
    a = num[pos1];
    num[pos1] = num[pos2];
    num[pos2] = a;
    return;
}
int removeElement(int* nums, int numsSize, int val) {
    //no need to consider the order
    //switch all val to the rear
    int first_Val = numsSize-1;
    int pos = numsSize-1;
    while(pos>=0){
        if(nums[pos] == val){
            switch_num(nums, first_Val, pos);
            pos--;
            first_Val--;
        }
        else{
            pos--;
        }
    }
    return first_Val+1;
}

算法学习

int removeElement(int* nums, int numsSize, int val) {
    int slow = 0, fast = 0; //一对夫妇,原本都是零起点
    while (fast < numsSize) {   //但是有一个跑得快,一个跑得慢
        if (nums[fast] != val) {    //于是跑得快的那个先去寻找共同目标
            nums[slow] = nums[fast];    //如果找到了,就送给跑得慢的那个
            slow++;     //然后跑得慢的那个也就离目标近一点
        }
        fast++; //但是不管是否找得到,跑得快的那方都一直奔跑到生命的尽头
    }
    return slow;    //最终留下跑得慢的一方
}

他的算法比我的简单,并且能够保持原来的顺序,值得学习。

3.  删除有序数组中的重复项

我的算法

int removeDuplicates(int* nums, int numsSize) {
    int slow = 1, fast = 1; // first element is always needed!
    while(fast < numsSize){
        if(nums[fast] <= nums[slow-1]){
        fast++;
    }
    else{
        nums[slow++] = nums[fast++];
    }
    }
    return slow;
}

学习了上一题的快慢指针,果然清晰明了多了。

4.  删除有序数组中的重复项 II

我的算法

int removeDuplicates(int* nums, int numsSize) {
    //Every element has 2 chances to show up
    int showup = 1;
    int slow = 1, fast = 1;
    while(fast < numsSize){
        //Meet new, showup = 2 - 1 
        if(nums[fast] != nums[slow-1]){
            nums[slow++] = nums[fast++];
            showup = 1;
        }
        else{
            if(showup){
                nums[slow++] = nums[fast++];
                showup--;
            }
            else{
                fast++;
            }
        }
    }
    return slow;
} 

我的思路

依旧是快慢指针

5. 多数元素

我的算法

int majorityElement(int* nums, int numsSize) {
    int pos = 1;
    int vote = nums[0];
    int cnt = 1;
    while(pos < numsSize){
        if(nums[pos] == vote){
            cnt++;
        }
        else{
            cnt--;
        }
        if(cnt<0){
            vote = nums[pos];
            cnt = 1;
        }
        pos++;
    }
    return vote;
}

我的思路

投票法,是一个值得牢记的思路

6. 买卖股票的最佳时机

我的算法

int maxSub(int* arr, int size){
    int max = -10000, this = 0;
    for(int i = 0; i < size; i++){
        this += arr[i];
        if(this > max){
            max =  this;
        }
        if(this < 0){
            this = 0;
        }
    }
    return (max>0)?max:0;
}
int maxProfit(int* prices, int pricesSize) {
    int* diff_price = malloc(sizeof(int)*pricesSize-1);
    for(int i = 0; i< pricesSize-1; i++){
        diff_price[i] = prices[i+1] - prices[i];
    }
    return maxSub(diff_price, pricesSize-1);
}

我的思路

相邻两天价格求差,然后利用最长子列和进行积分。

算法学习

一遍扫描,找到更低的价格后,把当前最好的情况和他相结合,看能不能找到更好的情况。(骑驴找马)

这道题核心在于,更低的价格不意味着能够找到更好的买家来换取更高的利润,所以要骑驴找马,之前最好的情况先记在心中,然后按着这个更低的价格来,看能不能超越之前的利润,超越了我就更新。

int maxProfit(int* prices, int pricesSize) {
    int best=  0, pos = 1;
    int max = prices[0], min = prices[0];
    while(pos < pricesSize){
        if(prices[pos] < min){
            min = prices[pos];
            max = min + best;
        }
        if(prices[pos] > max){
            max = prices[pos];
            best = prices[pos] - min;
        }
        pos++;
    }
    return best;
}

算法学习2

和算法学习1差不多的思路

int maxProfit(int* prices, int pricesSize) {
    int min = INT_MAX, best = 0;
    for(int i = 0; i < pricesSize; i++){
        min = prices[i]<min?prices[i]:min;
        best = prices[i]-min>best?prices[i]-min:best;
    }
    return best;
}

7.  最大子数组和

我的算法

int maxSubArray(int* nums, int numsSize) {
    int max = -29999, this = 0;
    for(int i =  0; i<numsSize; i++){
        this += nums[i];
        if(this > max){
            max = this;
        }
        if(this < 0){
            this = 0;
        }
    }
    return max;
}

我的思路

非常重要的题型,一定要倒背如流。

强化思路

试试分治法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值