IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 9月10日 算法练习 -> 正文阅读

[数据结构与算法]9月10日 算法练习

力扣题3:无重复字符的最长子串

思考:通过逻辑上的双指针和哈希表进行配合,时间复杂度可以化简到O(n),暴力的话需要找到每个子串O(n^2),然后查询是否有重复元素O(n),复杂度是n^3以上。所以用滑动窗口来做是很好的算法。

官方解释:

「滑动窗口」来解决这个问题了:

我们使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着上文中「枚举子串的起始位置」,而右指针即为上文中的?每一步的操作中,我们会将左指针向右移动一格,表示我们开始枚举下一个字符作为起始位置,然后我们可以不断地向右移动右指针,但需要保证这两个指针对应的子串中没有重复的字符。在移动结束后,这个子串就对应着 以左指针开始的,不包含重复字符的最长子串。我们记录下这个子串的长度;
在枚举结束后,我们找到的最长的子串的长度即为答案。
判断重复字符

在上面的流程中,我们还需要使用一种数据结构来判断 是否有重复的字符,常用的数据结构为哈希集合(即 C++ 中的 std::unordered_set,Java 中的 HashSet,Python 中的 set, JavaScript 中的 Set)。在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters/solution/wu-zhong-fu-zi-fu-de-zui-chang-zi-chuan-by-leetc-2/
来源:力扣(LeetCode)

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        //哈希集合,记录每个字符是否出现过
        unordered_set<char> occ;
        //rk 是左指针,ans是最大子串长度
        int rk=-1,ans=0;
        int n = s.size();
        for(int i = 0;i<n;i++){
            //移动左指针后,把字符从哈希表中除去
            if(i!=0){
                occ.erase(s[i-1]);
            }
            //如果有指针下一个位置还有字符,并且在哈希表中没有存储过该字符
            while(rk+1<n&&!occ.count(s[rk+1])){
                //将下一个字符插入到哈希表
                occ.insert(s[rk+1]);
                //有指针移动
                rk++;
            }
            //和上一次的答案进行比较取最大
            //从i到rk的子串数目
            ans = max(ans,rk-i+1);
        }
        return ans;
    }
};

力扣第5题:最长回文子串

方法:动态规划法

时间复杂度O(n^2)

空间复杂度O(n^2)

对于一个子串而言,如果它是回文串,并且长度大于?2,那么将它首尾的两个字母去除之后,它仍然是个回文串。例如对于字符串?“ababa”,如果我们已经知道?“bab”是回文串,那么?“ababa”一定是回文串,这是因为它的首尾两个字母都是?“a”。根据这样的思路,我们就可以用动态规划的方法解决本题。

class Solution {
public:
    string longestPalindrome(string s) {
        int n = s.size();
        //如果字符串长度为1,则他就是回文串。
        if(n<2) return s;
        int maxlen=1;
        int begin = 0;
        //定义二维数组,行列都是n
        vector<vector<int>> dp(n,vector<int>(n));
        //只有一个字符的子串是回文串
        for(int i= 0;i<n;i++){
            dp[i][i] = true;
        }
        //枚举所有子串长度
        for(int L=2;L<=n;L++){
            //枚举左边界
            for(int i=0;i<n;i++){
                //通过长度和左边界计算有边界
                int j = L+i-1;
                //如果有边界越界,则直接结束当前判断
                if(j>=n) break;
                
                //如果子串收尾字符不相等,则不是回文串
                if(s[i]!=s[j])dp[i][j]=false;
                else{
                    //如果子串字符相等,并且长度只有两个,则是回文子串
                    if(j-i<3)dp[i][j]=true;
                    else{
                        //通过长度比较短的子串来计算长度比较长的子串
                        dp[i][j]=dp[i+1][j-1];
                    }
                }
                //如果当前子串是回文串,并且长度大于先前记录的最大回文串的长度,则更新记录
                if(dp[i][j]&&j-i+1>maxlen){
                    maxlen = j-i+1;
                    begin = i;
                }
            }
        }
        //返回回文串
        return s.substr(begin,maxlen);
    }
    
};

AcWing 786 :第k个数

算法时间复杂度O(n)

思路:用分治递归的思想,把大问题逐渐转化为小问题,然后利用小问题来求解最后的答案。

#include<iostream>

using namespace std;

const int N = 1e5+10;
int q[N];
int n,k;


int quick_sort(int l,int r,int k){
    //如果数组就一个数,因为k肯定在数组中所以该数就是要返回的数
    if(l==r) return q[l];
    
    int i = l-1,j = r+1,x = q[l];
    
    //利用i , j把比分界点小的数放到左边,把比分界点大的数放到右边,并返回分界点的下标位置。
    while(i<j){
        while(q[++i]<x);
        while(q[--j]>x);
        if(i<j)swap(q[i], q[j]);
    }
    //获得分界点左边的数的个数
    int sl = j-l+1;
    //递归处理小区间,如果k在左边的区间,注意一定要包含=k不然会出错
    //k-sl表示k在右边区间的下标。
    if(sl>=k) return quick_sort(l, j, k);
    return quick_sort(j+1, r,k-sl);
}

int main(){
    cin>>n>>k;
    
    for(int i=0;i<n;i++){
        cin>>q[i];
    }
    
    cout<<quick_sort(0,n-1,k)<<endl;
    
    return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:43:26  更:2022-09-13 11:44:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 16:34:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码