1. 程式人生 > 其它 >Json格式校驗

Json格式校驗

回溯演算法

虛擬碼1:

result;//用於存放結果集

backTracking()
{
    if(滿足結束條件)
    {
        將結果新增到結果集中;
        return;
    }

    for(選擇in選擇列表)
    {
        修改;
        backTracking();//回溯
        回改;
    }
}

LeetCode46-全排列:給定一個不含重複數字的陣列nums,返回其所有可能的全排列。

class Solution {
public:
    vector<vector<int>> result;

    vector
<vector<int>> permute(vector<int>& nums) { backtracking(0,nums);//回溯 return result; } //回溯 void backtracking(int k,vector<int>& nums) { //if(滿足結束條件) if(k==nums.size()-1) { result.push_back(nums);
return; } //for(選擇in選擇列表) for(int i=k;i<nums.size();++i) { swap(nums[i],nums[k]);//修改 backtracking(k+1,nums);//回溯 swap(nums[i],nums[k]);//回改 } } };

LeetCode51-N皇后:將 n個皇后放置在 n×n 的棋盤上,並且使皇后彼此之間不能相互攻擊(任何兩個皇后都不能處於同一條橫行、縱行或斜線上)。給你一個整數 n ,返回所有不同的n皇后問題 的解決方案。每一種解法包含一個不同的n 皇后問題 的棋子放置方案,該方案中 'Q' 和 '.' 分別代表了皇后和空位。

class Solution {
public:
    vector<vector<string>> result;

    vector<vector<string>> solveNQueens(int n) 
    {
        if(n==0)
            return {};

        int row=0;//行數
        //矩陣result的某一行
        vector<string> board(n,string(n,'.'));
        //列colomn,左斜ldiag,右斜rdiag;記錄是否存在皇后
        vector<bool> colomn(n,false),ldiag(2*n-1,false),rdiag(2*n-1,false);

        BackTracking(colomn,ldiag,rdiag,board,row,n);//回溯

        return result;
    }

    //回溯
    void BackTracking(vector<bool>& colomn,vector<bool>& ldiag,vector<bool>& rdiag,vector<string>& board,int row,int n)
    {
        //滿足結束條件已經遍歷完了所有的行
        if(row>=n)
        {
            result.push_back(board);
            return;
        }
   
        for(int j=0;j<n;++j)//逐行判斷,並插入皇后
        {
            if(colomn[j]||ldiag[row+j]||rdiag[n-row+j-1])
                continue;

            board[row][j]='Q';
            colomn[j]=ldiag[row+j]=rdiag[n-row+j-1]=true;//修改

            BackTracking(colomn,ldiag,rdiag,board,row+1,n);//回溯
            
            board[row][j]='.';
            colomn[j]=ldiag[row+j]=rdiag[n-row+j-1]=false;//回改
        }    
    }
};

LeetCode71-組合:給定兩個整數nk,返回 1 ...n中所有可能的k個數的組合。

class Solution {
public:
    vector<vector<int>> result;

    vector<vector<int>> combine(int n, int k) 
    {       
        vector<int> comb(k,0);
        int count=0;

        BackTracking(comb,count,n,k,1);//回溯

        return result;
    }

    void BackTracking(vector<int>& comb,int count,int n,int k,int pos)
    {
        //if(滿足結束條件),已經選了k個數
        if(count==k)
        {
            result.push_back(comb);
            return;
        }

        //for(選擇in選擇列表)
        for(int i=pos;i<=n;++i)
        {
            comb[count++]=i;//修改
            BackTracking(comb,count,n,k,i+1);//回溯
            --count;//回改
        }
    }
};

虛擬碼2:

result;//用於存放結果集

backTracking()
{
    if(滿足結束條件)
    {
        將結果新增到結果集中;
        return;
    }

    for(選擇in選擇列表)
    {
        if(滿足條件)
        {
            修改;
            backTracking();//回溯
            回改;
        }
        else
        {
          break;
        } 
    }
}

LeetCode93-復原IP地址:給定一個只包含數字的字串,用以表示一個 IP 地址,返回所有可能從s獲得的有效 IP 地址。

class Solution {
public:
    vector<string> result;

    vector<string> restoreIpAddresses(string s) 
    {
        backtracking(s, 0, 0);//回溯

        return result;
    }
    
    //回溯
    void backtracking(string& s, int startIndex, int pointNum)
    {
        //if(滿足結束條件),點的數量已經夠了
        if(pointNum == 3)
        {
            //判斷剩下的字串是否符合條件
            if(isValid(s, startIndex, s.size() - 1))
                result.push_back(s);

            return;
        }

        //for(選擇in選擇列表)
        for(int i = startIndex; i < s.size(); i++)
        {
            if(isValid(s, startIndex, i))//i不同表示從不同的位置進行分割
            {
                s.insert(s.begin() + i + 1, '.');
                pointNum++;//修改

                backtracking(s, i + 2, pointNum);//回溯

                pointNum--;
                s.erase(s.begin() + i + 1);//回改
            }
            else 
                break;
        }
    }
    
    //判斷該段字串是否有效
    bool isValid(const string& s, int start, int end)
    {
        //s[start...end]以0開頭並且不是0(含前導項0)  或者  起止範圍不符合條件
        if(s[start] == '0' && start != end||start > end)
            return false;

        int num = 0;
        for(int i = start; i <= end; i++)
        {
            if(s[i] > '9' || s[i] < '0')//含有其他字元
                return false;

            num = num * 10 + (s[i] - '0');//計算該段字串表示的數字的大小
            if(num > 255)
                return false;
        }

        return true;
    }

};

LeetCode131-分割回文串:給你一個字串s,請你將s分割成一些子串,使每個子串都是迴文串。

class Solution {
public:
    vector<vector<string>> result;

    vector<vector<string>> partition(string s) 
    {
        if (s.empty())
            return {};

        vector<string> ans;

        backTracking(s, ans, 0);

        return result;
    }

    void backTracking(const string& s,  vector<string>& ans, int pos)
    {
        //if(滿足結束條件)
        if (pos >= s.length())
        {
            result.push_back(ans);
            return;
        }

        //for(選擇in選擇列表)
        for (int i = pos; i < s.length(); ++i)
        {
            string currStr = s.substr(pos, i-pos+1);

            if (IsPalindrome(currStr))//是迴文串,則進行回溯
            {
                ans.push_back(currStr);//修改
                backTracking(s, ans, i+1);//回溯
                ans.pop_back();//回改
            }
        }
    }

    //判斷當前字元是否是迴文:雙指標做法
    inline bool IsPalindrome(const string& currStr)
    {
        int l = 0;//左指標
        int r = currStr.size()-1;//右指標
        // 雙指標,從字串兩邊收縮去檢查
        while(l < r)
        {
            if (currStr[l] != currStr[r]) return false;
            l++; r--;
        }
        return true;
    }
};