[Algorithm][综合训练][求最小公倍数][跳台阶][最长回文子串]详细讲解


1.求最小公倍数

1.题目链接


2.算法原理详解 && 代码实现

  • 最小公倍数:两数乘积 / 最大公因数
  • 最大公因数:辗转相除法
    • 原理GCD(a, b) == GCD(b, a % b)
    // 非递归版本
    int GCD(int a, int b)
    {
    	while(b != 0)
    	{
    		int tmp = b;
    		b = a % b;
    		a = tmp;
    	}
    
    	return a;
    }
    
    int GCD(int a, int b)
    {
    	int tmp = 0;
    	while(a % b)
    	{
    		tmp = a % b;
    		a = b;
    		b = tmp;
    	}
    
    	return b;
    }
    
    // 递归版本
    int GCD(int a, int b)
    {
    	if(b == 0)
    	{
    		return a;
    	}
    
    	return GCD(b, a % b);
    }
    
  • 代码
    #include <iostream>
    using namespace std;
    
    int GCD(int a, int b)
    {
    	if(b == 0)
    	{
    		return a;
    	}
    
    	return GCD(b, a % b);
    }
    
    int main()
    {
    	int a = 0, b = 0;
    	cin >> a >> b;
    
    	cout << (a * b / GCD(a, b)) << endl;
    
    	return 0;
    }
    

2.跳台阶

1.题目链接


2.算法原理详解 && 代码实现

  • 自己的版本
    #include <iostream>
    #include <vector>
    using namespace std;
    
    int main()
    {
        int n = 0;
        cin >> n;
    
        vector<int> dp(n + 1, 0);
        dp[1] = 1, dp[2] = 2;
    
        for(int i = 3; i <= n; i++)
        {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
    
        cout << dp[n] << endl;
    
        return 0;
    }
    
  • 优化版本:相较于自己的版本,多了滚动数组进行空间优化
    #include <iostream>
    using namespace std;
    
    int main()
    {
        int n = 0;
        cin >> n;
    
        int a = 1, b = 2, c = 2;
        for(int i = 3; i <= n; i++)
        {
            c = a + b;
            a = b;
            b = c;
        }
        
        if(n == 0 || n == 1)
        {
            cout << n << endl;
        }
        else
        {
            cout << c << endl;
        }
        
        return 0;
    }
    

3.最长回文子串

1.题目链接


2.算法原理详解 && 代码实现

  • 自己的版本:动态规划 --> 时间/空间复杂度均为 O ( N 2 ) O(N^2) O(N2)
    int getLongestPalindrome(string A) 
    {
        int n = A.size();
        vector<vector<bool>> dp(n, vector<bool>(n, false));
    
        int len = 1;
        for(int i = n - 1; i >= 0; i--)
        {
            for(int j = 0; j < n; j++)
            {
                if(A[i] == A[j])
                {
    	            // i + 1 < j -> 表示至少有三个字符或以上
                    dp[i][j] = i + 1 < j ? dp[i + 1][j - 1] : true;
    
                    if(dp[i][j] && j - i + 1 > len)
                    {
                        len = j - i + 1;
                    }
                }
            }
        }
    
        return len;
    }
    
  • 优化版本:中心扩展算法 --> 时间复杂度 O ( N 2 ) O(N^2) O(N2),空间复杂度 O ( 1 ) O(1) O(1)
    • 枚举中心位置的时候,要考虑回文串长度的奇偶性
    int getLongestPalindrome(string A) 
    {
    	int n = A.size(), len = 1;
    
    	for(int i = 1; i < n; i++) // 枚举每个中心点
    	{
    		// 当长度是奇数时
    		int left = i - 1, right = i + 1;
    		while(left >= 0 && right < n && A[left] == A[right])
    		{
    			left--;
    			right++;
    		}
    		len = max(len, right - left - 1);
    
    		// 当长度是偶数时
    		left = i - 1, right = i;
    		while(left >= 0 && right < n && A[left] == A[right])
    		{
    			left--;
    			right++;
    		}
    		len = max(len, right - left - 1);
    	}
    	
    	return len;
    }
    
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是使用QT实现Manacher算法的代码,同时包括了QT窗口的输入和输出。 首先,我们需要在QT Creator中创建一个新的Qt Widgets项目,然后在mainwindow.cpp文件中添加下面的代码: ``` #include "mainwindow.h" #include "ui_mainwindow.h" #include <QString> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(findLongestPalindrome())); } MainWindow::~MainWindow() { delete ui; } void MainWindow::findLongestPalindrome() { QString str = ui->lineEdit->text(); QString result = longestPalindrome(str); ui->label->setText(result); } QString MainWindow::longestPalindrome(QString s) { QString t = "$#"; for (int i = 0; i < s.length(); ++i) { t += s.at(i); t += "#"; } int p[t.length()] = {0}; int mx = 0, id = 0, maxLength = 0, centerIndex = 0; for (int i = 1; i < t.length(); ++i) { p[i] = mx > i ? std::min(p[2 * id - i], mx - i) : 1; while (t[i + p[i]] == t[i - p[i]]) { ++p[i]; } if (mx < i + p[i]) { mx = i + p[i]; id = i; } if (maxLength < p[i]) { maxLength = p[i]; centerIndex = i; } } QString res; for (int i = centerIndex - maxLength + 1; i < centerIndex + maxLength; ++i) { if (t[i] != '#') { res += t[i]; } } return res; } ``` 在这段代码中,我们使用了QT的信号槽机制,将按钮的点击事件连接到了findLongestPalindrome()槽函数。该函数中,首先获取输入框中的字符串,然后调用longestPalindrome()函数来计算最长回文子串,最后将计算结果显示在label标签中。 longestPalindrome()函数实现了Manacher算法,对输入字符串进行预处理,并维护了变量p、mx、id、maxLength和centerIndex,最终返回最长回文子串。 下面是mainwindow.h文件的代码: ``` #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); QString longestPalindrome(QString s); public slots: void findLongestPalindrome(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H ``` 最后,在mainwindow.ui文件中添加下面的控件: - QLineEdit:用于输入字符串。 - QPushButton:用于触发计算最长回文子串的按钮。 - QLabel:用于显示计算结果。 然后,将这些控件与对应的槽函数和变量进行连接,就可以运行这个程序了。 注意:为了能够正常使用QString类和std::min函数,需要在mainwindow.cpp文件中添加下面两行代码: ``` #include <QString> #include <algorithm> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DieSnowK

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值