动态规划(最长回文字串)&&利用dfs (vector)写简单路径

https://leetcode-cn.com/problems/longest-palindromic-substring/

Dp 题!

class Solution {
public:
    string longestPalindrome(string a) {
    int n=a.size();
    int max=1;
    int begin=0;
    string ans;
    vector<vector<int>>  A(n,vector<int>(n));

    for (int j = 0; j < n; ++j) {
        for (int i = 0; i < n; ++i) {
            if (i==j){
                A[i][j]=1;
            } 
            else{
                A[i][j]=0;
            }
        }
    }
    for (int j = 1; j < n; ++j) {
        for (int i = 0; i < j; ++i) {
            if (a[i]!=a[j]){
                A[i][j]=0;
            }else{
                if (j-i<3){
                    A[i][j]=1;
                }else{
                    A[i][j]=A[i+1][j-1];
                }
            }
            if (A[i][j]==1&&j-i+1>max){
                max=j-i+1;
                begin=i;
            }
        }
    }
    ans=a.substr(begin,max);
    return ans;
    }
};

利用dfs 写简单路径
其中用到了类 father 第一个用类写的数据结构和算法题 也算是利用了c++吧

先在就来说说吧!

  1. 定义一个father类
  2. father类中成员变量是程序共有的 然后写出成员函数
  3. 在外边复现出成员函数的主体
  4. 然后调用就行 其他的细节准备在代码中注释
    多的不说上代码
#include<iostream>
#include <vector>
using namespace std;
class father{   //有向图的简单路径
private:
    vector<int> path;
    int count;
    int start;
    int **map;    // 存邻接矩阵
    int end;     // 终点
    int length;  //要求的路径长度  用户输入
    int temp;   //path路径长度  有效长度
public:
    father(int count , int start ,int end ,int k);//用于初始化上面的变量
    ~father();//析构函数  类加载完后进行内存的释放
    void creat(); // 创建邻接矩阵
    void commondfs(int v); //找出所有从start 到 end  的简单路径
    void specialdfs(int v);//找出从start 到 end 且路径长度为 length的路径
    void print();//打印路径的函数
    int findnext(int v,int con);//找到下一个邻接点   con代表着V的第CON个邻接点
    bool iscircle(int next);//判断是否路径是否形成环路
};
father::father(int total, int s, int e, int k) {
    count=total;
    start=s;
    end=e;
    length=k;//对各个变量的初始化
    path.push_back(s);  //入起点
    temp=0;//此时路径长度是1
    map=new int*[total];  //申请二维数组的空间   新方法
    for (int i = 0; i < total; ++i) {
        map[i]=new int[total];  //申请二维数组中底层的空间
    }
}
father::~father() {  //析构函数  释放内存
    delete [] map;
}

void father::creat() { //构建邻接矩阵   有向图
    int a;
    for (int i = 0; i < count; ++i) {
        for (int j = 0; j < count; ++j) {
            cin>>a;
            map[i][j]=a;
        }
    }
}

void father::commondfs(int v) { //搜索所有路径
    if (v==end){  //递归出口  如果找到终点则结束
        print();  //打印路径
        return ;
    }
    int con = 0;  //当前为0代表V的第一个邻接点
    int next =findnext(v,con);  //通过findnext找到第一个邻接点
    while(next != -1){  //判断是否找到
        while (iscircle(next)){  //判断 找到的邻接点会不会和之前的路径构成回路
            con++; //如果构成回路  则上一个next不能选  找第二个邻接点  然后判断
            next=findnext(v,con); //依次类推

        }
        path.push_back(next);//当我们找到一个不构成环路的邻接点时候  加入路径
        commondfs(next); //递归找next 的邻接
        path.pop_back();  //走到这里的时候 可能是走完一条路径   或者是走不到终点 需要重新选取next
        //v=path.back(); //把之前存的next出队  并且拿到next之前的那个值  可写可不写
        con++; //对con进行加一  表示V的下一个邻接点
        next=findnext(v,con);//找邻接点
    }
}
void father::specialdfs(int v) {  //特殊的dfs  对路径进行判断 筛选路径
    if (v==end&&temp==length){  //递归出口  找到终点 而且 路径长度是length则出
        print();//打印
        return ;
    }
    if (v==end){//找到终点但不是所要的长度也需要返回 因为返回找其他路
        return ;
    }
    int con=0;//和上面commondfs差不多
    int next= findnext(v,con);
    while(next!=-1){
        while (iscircle(next)){
            con++;
            next=findnext(v,con);
        }
        vector<int>::iterator it=path.end()-1;//使用迭代器返回末尾的元素的迭代器
        path.push_back(next);  //找到的邻接点存进去
        temp+=map[*it][path.back()]; //表示*it到next 的路径长度
        specialdfs(next);//递归找下一个
        temp-=map[*it][path.back()];//回溯到找到上一个next之前的路径长度
        path.pop_back(); //出栈上一个next
        //v=path.back();  拿到末尾的节点 也就是我们之前的V
        con++;
        next=findnext(v,con);  //找到下一个路径
    }
}
void father::print() {  //打印
    vector<int>::iterator it=path.begin();
    for(;it<path.end()-1;it++)
        cout<<*it<<"->";
    cout<<*it<<endl;
}
int father::findnext(int v, int con) {  //找邻接点
    int a=-1,k=0;  //a=-1 表示没找到邻接点 返回-1
    for (int j = 0; j < count; ++j) {  
        if (map[v][j]!=0){  //找到邻接点
            if(k==con){  //判断是不是第con个邻接点
                a=j ;  //返回点
                break;
            }
            k++; //  如果不是第con个邻接点 则继续   注意con 和实际第几个邻接点的区别
            /*f(k>con){  //可要可不要  写上方便了解
                break;
            }*/
        }
    }
    return a;
}
bool father::iscircle(int next) {  //判断是否是环
    //看当前的邻接点与(除了path中的最后一个点)path中的点是否相同 相同则有回路  反之没有  不理解画个图 可理解
    for (vector<int>::iterator it=path.begin();it<path.end()-1;it++) {
        if (*it==next){
            return true;
        }
    }
    return false;
}
int main(){
    cout<<"请输入节点数  起点  终点  和  路径长度"<<endl;
    int n,x,y,len;
    cin>>n>>x>>y>>len;
    father a(n,x,y,len);
    cout<<"请输入你的邻接矩阵"<<endl;
    a.creat();
    cout<<"所有简单路径为--->"<<endl;
    a.commondfs(x);
    cout<<"路径长度为"<<len<<"的路径分别是-->" <<endl;
    a.specialdfs(x);
}

测试结果

请输入节点数  起点  终点  和  路径长度
5 0 4 4
请输入你的邻接矩阵
0 1 1 0 0
0 0 0 1 2
0 0 0 1 0
1 0 0 0 2
0 0 0 0 0
所有简单路径为--->
0->1->3->4
0->1->4
0->2->3->4
路径长度为4的路径分别是-->
0->1->3->4
0->2->3->4

今天就到这里了 加油 打工人!!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值