2021-5-17学习记录寻找第k大/跳台阶/子数组的最大累加和

主题:

学习记录,包括:

  • 算法题:寻找第K大的数字
  • 算法题:跳台阶
  • 算法题:子数组的最大累加和

内容:

1 寻找第K大的数字
题目描述:
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
思路:不可以直接在这个函数里进行递归,因为没有函数的递归的条件,因此可以再写一个函数
来进行递归。完全是快速排序的思路,只是由于必定有解,再加上有二分查找的性质,因此可以不必使用
最外层的条件。不同于快速排序,这里只是一个查找,不需要两边都排序,只是向目标在的那一边就可以
注意:第k大,说明是从后面向前数,第k个数。n-k表示这个值对应的下标。
插入图片

int findKth(vector<int> a, int n, int K) {
        // write code here
        return quick_sort(a, 0, n-1, n, K);
    }
    
    int quick_sort(vector<int>&a, int start, int end, int n,int k)
    {
        
            int left = start;
            int right = end;
            int pivot = a[left];
            int res = 0;
            while(left<right)  //递归实现
            {
                while(left<right && a[right]>=pivot)
                {
                    right--;
                }
                if(left<right)
                {
                    a[left] = a[right];
                    left++;
                }
                while(left<right && a[left]<=pivot)
                {
                    left++;
                }
                if(left<right)
                {
                    a[right] = a[left];
                    right--;
                }
            }
            a[left] = pivot;
        
            if(left == n-k) return pivot;  //如果该pivot的排序确实是第k个的话
            else if(left<n-k)
            {
                 res =quick_sort(a, left+1, end, n, k);
            }
            else{
                res = quick_sort(a, start, right-1,n,k);
            }
            return res;
    }

2 跳台阶
问题描述:一只青蛙一次可以跳上1级台阶,也可以跳上2级。
求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。
思路:
1 一般递归思路:设置一个类内公共变量,在每一次递归的时候,判断是不是n为1或0
如果是的话,那么说明这条路走到这里已经结束了,那么公共变量就++,退出,否则,就继续向
下面尝试,也就是调用n-1,n-2作为参数的本函数
2 非记忆动态规划(递归实现):n个台阶有一个状态量,表示可以有几种走法。那么就有状态
转移方程 n的状态量 = n-1的状态量 + n-2的状态量。 因为一次要么跳一次,要么跳两次
3 记忆化动态规划(递归实现):把算过的n对应的状态量存储起来,下次使用到的时候,直接使用
这个举措,可以使得时间效率提高大概100倍
4 动态递归(非递归实现):从dp[0],dp[1]以经可以确定值来出发,从后向前来算出全部的dp值
最后输出dp[n]
代码:


int num = 0;
    int jumpFloor(int number) {
        //countNum(number);  //这种方法的时间复杂度太大,会超时
        //return num;
        
        //return Fibonacci(number);
        
        //return F2(number);  //这种方法更好一点,时间直接变成原来的1/100
        
        return Fibonacci3(number);
    }
    
    void countNum(int stage)
    {
        if(stage <= 1)
        {
            num++;
            return;
        }
        else{
            countNum(stage-1);
            countNum(stage-2);
        }
    }
    
    //这个方法的时间复杂度也是o(n*n)空间复杂度是递归栈的空间
    //存在多个重复计算,因此可以把计算过的来存储下来
    int Fibonacci(int n) //假设f(i)表示第i个台阶的可能的方法数,那么第i个台阶的方法数=第i-1个台阶的方法数和第i-2个台阶的方法数
    {
        if(n<=1)
            return 1;
        return Fibonacci(n-1)+Fibonacci(n-2);
    }
    
    int F2(int n)  //创建一个数组变量dp,然后,调用Fibonacci2
    {
        vector<int> dp(45,-1); //用-1来进行初始化,因为正常都是正值,用-1表示还没有算过
        return Fibonacci2(n, dp);
    }
    //采用记忆化的方法,来防止多次重复计算,不过需要知道数组的大小,或者直接用map
    int Fibonacci2(int n, vector<int>& dp)
    {
        if(n<=1) return 1;
        if(dp[n]!=-1) return dp[n];
        return dp[n] = Fibonacci2(n-1, dp)+Fibonacci2(n-2, dp);  //否则进行计算,计算后要赋值,然后返回
    }
    
    //由于前面方法使用动态规划,是通过递归来实现,从上向下递归,然后从下向上回溯。
    //实际上想要计算出所有节点的状态值,完全可以采用非递归方式,从底部开始,向上进行计算,只需要知道最后的几个的值,然后向前计算即可
    //这种方法可以优化空间,避免多层递归调用导致的栈空间浪费
    int Fibonacci3(int n)
    {
        vector<int> dp(n+1, 0); //vector支持动态定义大小
        dp[0] = dp[1] = 1;
        for(int i=2;i<=n;i++)
        {
            dp[i] = dp[i-1]+dp[i-2];
        }
        return dp[n];
    }

3 子数组的最大累加和
题目描述:给定一个数组arr,返回子数组的最大累加和
例如,arr = [1, -2, 3, 5, -2, 6, -1],所有子数组中,[3, 5, -2, 6]可以
累加出最大的和12,所以返回12.
题目保证没有全为负数的数据
时间复杂度为O(n),空间复杂度为O(1)
思路:可以这么想,我们从第一个元素开始,考虑是否加入下一个元素。当加入下一个元素的和
比当前元素的要大的时候,需要加入,也就是“加上前面的总是比自己搞要好”。
否则就不会加入到前面的元素,因为自己干会更好,这个时候,相当于就断了。
当然即使加上去,可能这个和本身是减小的,但是也会有后面的机会。因此需要加上一个和
的最大值记录。
代码:

int maxsumofSubarray(vector<int>& arr) {
        // write code here
        int m = 0;
        if(arr.size()==1)
        {
            return arr[0];
        }
        for(int i=1;i<arr.size();i++)
        {
            arr[i] = max(arr[i], arr[i-1]+arr[i]); //当和前面的一个进行比较 
            m = max(m, arr[i]);
        }
        return m;
    }

------------------------------end----------------------------
如果有帮助的话,不妨点一个赞??

### 关于 UniApp 框架推荐资源与教程 #### 1. **Uniapp 官方文档** 官方文档是最权威的学习资料之一,涵盖了从基础概念到高级特性的全方位讲解。对于初学者来说,这是了解 UniApp 架构技术细节的最佳起点[^3]。 #### 2. **《Uniapp 从入门到精通:案例分析与最佳实践》** 该文章提供了系统的知识体系,帮助开发者掌握 Uniapp 的基础知识、实际应用以及开发过程中的最佳实践方法。它不仅适合新手快速上手,也能够为有经验的开发者提供深入的技术指导[^1]。 #### 3. **ThorUI-uniapp 开源项目教程** 这是一个专注于 UI 组件库设计实现的教学材料,基于 ThorUI 提供了一系列实用的功能模块。通过学习此开源项目的具体实现方式,可以更好地理解如何高效构建美观且一致的应用界面[^2]。 #### 4. **跨平台开发利器:UniApp 全面解析与实践指南** 这篇文章按照章节形式详细阐述了 UniApp 的各个方面,包括但不限于其工作原理、技术栈介绍、开发环境配置等内容,并附带丰富的实例演示来辅助说明理论知识点。 以下是几个重要的主题摘选: - **核心特性解析**:解释了跨端运行机制、底层架构组成及其主要功能特点。 - **开发实践指南**:给出了具体的页面编写样例代码,展示了不同设备间 API 调用的方法论。 - **性能优化建议**:针对启动时间缩短、图形绘制效率提升等方面提出了可行策略。 ```javascript // 示例代码片段展示条件编译语法 export default { methods: { showPlatform() { console.log(process.env.UNI_PLATFORM); // 输出当前平台名称 #ifdef APP-PLUS console.log('Running on App'); #endif #ifdef H5 console.log('Running on Web'); #endif } } } ``` #### 5. **其他补充资源** 除了上述提到的内容外,还有许多在线课程视频可供选择,比如 Bilibili 上的一些免费系列讲座;另外 GitHub GitCode 平台上也有不少优质的社区贡献作品值得借鉴研究。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值