【每日刷题】Day109

【每日刷题】Day109

🥕个人主页:开敲🍉

🔥所属专栏:每日刷题🍍

🌼文章目录🌼

1. 179. 最大数 - 力扣(LeetCode)

2. 376. 摆动序列 - 力扣(LeetCode)

3. 21. 合并两个有序链表 - 力扣(LeetCode)

1. 179. 最大数 - 力扣(LeetCode)

//思路:排序+贪心。

//本题的重点还是在于贪心,题目的要求是让我们重新排列数字,使得能够得到最大的数,先来看看测试用例:

class Solution {

public:

    void swap(int& x, int& y)

    {

        int tmp = x;

        x = y;

        y = tmp;

    }

    string largestNumber(vector<int>& nums)

    {

        string ans;

        for (int i = 0; i < nums.size() - 1; i++)

        {

            for (int j = 0; j < nums.size() - 1 - i; j++)

            {

//两个数的两种组合

                string tmp1;

                string tmp2;

                tmp1+=to_string((long long)nums[j]);

                tmp1 += to_string((long long)nums[j+1]);

                tmp2 += to_string((long long)nums[j+1]);

                tmp2 += to_string((long long)nums[j]);

//交换情况

                if (tmp1.compare(tmp2)<0) swap(nums[j], nums[j + 1]);

            }

        }

        for(int i = 0;i<nums.size();i++) ans+=to_string((long long)nums[i]);

//处理数组中全为0的情况

        if(nums[0]==0) return "0";

        return ans;

    }

};

2. 376. 摆动序列 - 力扣(LeetCode)

//思路:贪心。

//本题的贪心策略如果不画图的话还是比较难想出来的。那我们来画一下图:

//由此我们找到了贪心的策略,遍历数组,计算波峰和波谷的总数,就是最终最长摆动子序列的长度。

//那么现在难点就在于如何判断是否为波峰或者波谷,因为我们会遇到如下四种情况:

//由此我们可以想出一个策略,通过一个点左右两边路段的增减趋势判断这个点是否为波峰或者波谷,这里就需要一个left变量记录上一个路段是增还是减。如果遇到了不增不减的路段,我们直接跳过路段中间的点,并且不更新left的值。

class Solution {

public:

    int wiggleMaxLength(vector<int>& nums)

    {

//ans为最终结果,left为上一个路段的增减趋势,初始为0是因为第一个点必定要记录,因为第一个点一定是波峰或者波谷

        int ans = 0,left = 0;

        for(int i = 1;i<nums.size();i++)

        {

//right为下一路段的增减趋势

            int right = nums[i]-nums[i-1];

//如果当前路段不增不减,直接跳过当前路段

            if(!right) continue;

//left*right < 0 说明两路段的增减趋势相反,则说明当前点为波峰或者波谷;left*right == 0说明当前为第一个点。

            if(left*right<=0) ans++;

            left = right;

        }

//返回ans+1因为上述循环结束后不会记录最后一个点,而最后一个点也是必定记录的

        return ans+1;

    }

};

3. 21. 合并两个有序链表 - 力扣(LeetCode)

//思路:递归。

//我们遍历list1和list2,不断比较list1和list2的val大小,让小的那个作为头节点,随后继续合并剩余的链表。

/**

 * Definition for singly-linked list.

 * struct ListNode {

 *     int val;

 *     ListNode *next;

 *     ListNode() : val(0), next(nullptr) {}

 *     ListNode(int x) : val(x), next(nullptr) {}

 *     ListNode(int x, ListNode *next) : val(x), next(next) {}

 * };

 */

class Solution {

public:

    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2)

    {

//当其中一个为空时,返回另外一个链表的节点

        if(!list1) return list2;

        if(!list2) return list1;

//获取list1->val和list2->val

        int ret1 = list1->val,ret2 = list2->val;

//如果ret11 <= ret2,让list1当前节点作为头节点,next指向剩余链表

        if(ret1<=ret2) list1->next = mergeTwoLists(list1->next,list2);

//反之让list2作为头节点,next指向剩余链表

        else list2->next = mergeTwoLists(list1,list2->next);

//选择较小的节点作为链表头节点返回

        if(ret1<=ret2) return list1;

        return list2;

    }

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值