力扣刷题31-33(力扣 0024/0070/0053)

今日题目:

24. 两两交换链表中的节点

题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)

思路:

看了例子,考虑一下三个的情况下最后一个是否交换,看这个栗子的情况,最后一个不用管,那就简单了。

直接for循环i一步走两个,凉凉交换即可

图解:

代码:

cpp 复制代码
class Solution {
public:
    void swap_node(ListNode*& pre, ListNode*& p, ListNode*& pnext) {
        ListNode* pnext_next = pnext->next;
        pre->next = pnext;
        pnext->next = p;
        p->next = pnext_next;
    }
    ListNode* swapPairs(ListNode* head) {
        if (!head || !head->next)
            return head;
        ListNode* dummy = (ListNode*)malloc(sizeof(ListNode));

        dummy->next = head;
        ListNode* pre = dummy;
        ListNode* p = head;
        while (p &&p->next ) {
            ListNode* pnext = p->next;
            ListNode* p_next = p->next->next;
            swap_node(pre, p, pnext);
            pre = p;
            p = p_next;
        }
        head = dummy->next;
        
        return head;
    }
};

写代码的时候犯了个sb错误:代码中使用了 malloc 来分配内存,应该使用 free 来释放内存,而不是 delete

在 C++ 中,建议尽量避免使用 mallocfree,而是使用 newdelete 运算符来进行内存分配和释放。

本题over


70. 爬楼梯

题目:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

**每次你可以爬 12 个台阶。**你有多少种不同的方法可以爬到楼顶呢?

思路:

每次你可以爬 12 个台阶。看到这个就想到了动态规划。

想一下起始条件 :一开始没有楼梯,1种方法,试一下n=0结果,expected 'n' to have value from 1 to 45 only如果只有一层n=1,此时结果也为1,所以两个起始条件n=0,ans=1;n=1;ans=1;

中间过程:

假设跳上n级台阶有 ans(n) 种跳法。在所有跳法中,最后一步只有两种情况: 跳上 1 级或 2 级台阶。

当为 1 级台阶: 剩 n−1 个台阶,此情况共有 ans(n-1) 种跳法。

当为 2 级台阶: 剩 n−2 个台阶,此情况共有 ans(n-2) 种跳法。

即 ans(n)为以上两种情况之和,即 ans(n)= ans(n-1) +ans(n-2).

所以代码如下:
cpp 复制代码
class Solution {
public:
    int climbStairs(int n) {
        vector<int>ans(n+1);
        ans[0]=ans[1]=1;
        for(int i=2;i<=n;i++){
            ans[i]=ans[i-1]+ans[i-2];
        }
        return ans[n];
    }
};
注意:

一开始我是按照下面的写法写的结果报错:

cpp 复制代码
 vector<int>ans;
 ans[0]=ans[1]=1;

Line 1037: Char 34: runtime error: applying non-zero offset 4 to null pointer (stl_vector.h) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1046:34

这个问题就是。在使用 vector<int> ans; 声明向量后,你直接尝试访问 ans[0]ans[1] 来给这两个位置赋值,这是不正确的。因为在声明向量后,它是空的,没有任何元素,所以不能直接通过下标访问元素。

为了解决这个问题,可以使用 push_back 函数向向量中添加元素,或者在声明向量时指定大小。

改正如下:

cpp 复制代码
 vector<int>ans(n+1);
 ans[0]=ans[1]=1;

又over一道题


53. 最大子数组和

题目:

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。

思考:

首先想到动态规划的方法,找转移方程,因为需要找连续子数组,如果用dp[i]表示i开头的话,不如表示结尾,这样dp[i]存储的就是连续的和,这样dp[i]=(dp[i-1]+nums[i],dp[i]);最后返回最大值.

cpp 复制代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int n=nums.size();
        vector<int> dp(n);
        dp[0]=nums[0];
        for(int i=1;i<n;i++){
            dp[i]=max(dp[i-1]+nums[i],nums[i]);
        }
        sort(dp.begin(), dp.end());
        return dp[n-1];
    }
};
改进:

反正都是返回最大值不如直接一个常量+max函数搞定。用dp的话开数组+排序消耗太大。

首先,我们定义一个变量 maxSum 用于存储全局最大子序和,另一个变量 currentSum 用于存储当前子序和,初始值都设为数组中的第一个元素。

接下来,我们遍历数组,对于每个元素,我们更新 currentSummax(currentSum + nums[i], nums[i]),这代表着以当前元素结尾的子序列的最大和。然后,我们将 maxSum 更新为 max(maxSum, currentSum),这样我们就能不断更新全局最大子序和。

cpp 复制代码
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int maxSum=nums[0];
        int currentSum= nums[0];
        for(int i=1;i<nums.size();i++){
            currentSum=max(nums[i],currentSum+nums[i]);
            maxSum=max(currentSum,maxSum);
        }
        return maxSum;
    }
};

以上三道题over

相关推荐
格林威22 分钟前
常规线扫描镜头有哪些类型?能做什么?
人工智能·深度学习·数码相机·算法·计算机视觉·视觉检测·工业镜头
Lucis__1 小时前
再探类&对象——C++入门进阶
开发语言·c++
北京不会遇到西雅图2 小时前
【SLAM】【后端优化】不同优化方法对比
c++·机器人
jndingxin2 小时前
c++多线程(6)------ 条件变量
开发语言·c++
程序员莫小特2 小时前
老题新解|大整数加法
数据结构·c++·算法
过往入尘土3 小时前
服务端与客户端的简单链接
人工智能·python·算法·pycharm·大模型
zycoder.3 小时前
力扣面试经典150题day1第一题(lc88),第二题(lc27)
算法·leetcode·面试
Dream it possible!4 小时前
LeetCode 面试经典 150_哈希表_存在重复元素 II(46_219_C++_简单)
leetcode·面试·散列表
蒙奇D索大4 小时前
【数据结构】考研数据结构核心考点:二叉排序树(BST)全方位详解与代码实现
数据结构·笔记·学习·考研·算法·改行学it
洲覆4 小时前
C++ 模板、泛型与 auto 关键字
开发语言·数据结构·c++