劍指offer(1-20)

1.定義棧的數據結構,請在該類型中實現一個能夠得到棧中所含最小元素的min函數(時間複雜度應爲O(1))。

思路:需要兩個棧,主棧和輔助棧,每次插入主棧的值時確定,插入的值比輔助棧top大還是比輔助棧top小,只有在輔助棧的size爲0或者比輔助棧小的情況下入輔助棧棧,pop操作也是同理,pop的值與輔助棧做比較,當相同時輔助棧做出棧操作。

class Solution {
public:
    void push(int value) {
        obj_stack.push(value);
        if(min_stack.size() == 0)
        {
            min_stack.push(value);
            return ;
        }
        if(min_stack.top() >= obj_stack.top() )
        {
            min_stack.push(value);
            return ;
        }
    }
    void pop() {
        if(min_stack.top()==obj_stack.top())
        {
            min_stack.pop();
        }
        obj_stack.pop();
        
    }
    int top() {
        return obj_stack.top();
    }
    int min() {
        return min_stack.top();
        
    }
    private:
    stack<int> min_stack,obj_stack;
};


2.輸入一顆二叉樹的根節點和一個整數,打印出二叉樹中結點值的和爲輸入整數的所有路徑。路徑定義爲從樹的根結點開始往下一直到葉結點所經過的結點形成一條路徑。(注意: 在返回值的list中,數組長度大的數組靠前)

思路分析:需要一個vector<vector>和vector,用遞歸函數求出每條路徑,當滿足條件時,將該路徑壓入vector<vector>中,再pop_back,最後返回vector<vector>。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
            if(root == nullptr)
                return result;
        _FindPath(root,expectNumber);
        return result;
    }
    
    void _FindPath(TreeNode* root,int expectNumber) 
    {
        temp.push_back(root->val);
        if(root->left == nullptr && root->right == nullptr && expectNumber-root->val == 0)
        {
            result.push_back(temp);
        }
        if(root->left)
        _FindPath(root->left,expectNumber- root->val);
        if(root->right)
        _FindPath(root->right,expectNumber- root->val);
        temp.pop_back();
        
    }
 private:
    vector<int> temp;
    vector<vector<int>> result;
};

3。從上往下打印出二叉樹的每個節點,同層節點從左至右打印。
思路分析:用一個vector或者queue保存每一層的節點,需要注意的是層序遍歷,不能使用遞歸,而要使用迭代,因爲vector的頭刪效率比較低所以下面的代碼可以將in改成queue的類型,使用pop函數刪除

class Solution {
public:
	vector<int> PrintFromTopToBottom(TreeNode* root) {
		vector<int> out;
		if (root == nullptr)
			return out;
		in.push_back(root);
		while (!in.empty())
		{
			out.push_back(in.front()->val);
			if (in.front()->left != nullptr)
				in.push_back(in.front()->left);
			if (in.front()->right != nullptr)
				in.push_back(in.front()->right);
			in.erase(in.begin());
		}
		return out;
	}
private:
	vector<TreeNode*> in;

};

4.輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
思路:所謂的二叉搜索樹,左子樹比根小,右子樹比根大,後序遍歷爲左右根最後一個爲根節點,可以用根從後往前比較大小,當一個數比根節點小下標爲i-1,這個節點就算是左子樹的最大序列的節點,再該序列將分爲(begin,i-1)和(i,end-1)進行遞歸函數運算,輸出結果。

class Solution {
public:
	bool VerifySquenceOfBST(vector<int> sequence)
	{
		if (sequence.size() == 0)
			return false;
		return judge(sequence, 0, sequence.size() - 1);
	}

	bool judge(vector<int> sequence, int begin, int end)
	{
		if (begin >= end)
			return true;

		int i = end;

		while (i > begin && sequence[i-1] >= sequence[end])
		{
			i--;//最終的左子樹的最大下標
		}
		for (int j = i-1; j >= begin; j--)
		{
			if (sequence[j] > sequence[end])
				return false;
		}

		return (judge(sequence, begin, i-1)) && (judge(sequence, i, end-1));
	}
};

5.輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能爲該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)
思路分析:設置一個輔助棧,將壓入序列按順序壓入輔助棧中,每次判斷是否和彈出序列的首個成員比較值是否相同,如果相同,則將該成員從輔助棧和彈出序列中刪除,彈出序列的下一個元素成爲新的首部序列,while循環直到將所有的壓入順序都判斷一遍,再判斷彈出序列是否爲空,如果爲空返回true否則返回false。

class Solution {
public:
	bool IsPopOrder(vector<int> pushV, vector<int> popV) {
		if (pushV.size() == 0)
			return false;
		int i = 0;
		while (i != pushV.size())
		{
			in.push(pushV[i++]);
			while (in.size() != 0 && in.top() == popV.front())
			{
				in.pop();
				popV.erase(popV.begin());
			}
		}
		if (popV.size() != 0)
			return false;
		return true;

	}
private:
	stack<int> in;
};

6.給定一個double類型的浮點數base和int類型的整數exponent。求base的exponent次方。

保證base和exponent不同時爲0
思路分析:感覺這題挺沙雕的,判斷一下,次方是否大於零,如果大於,就累乘,如果小於則base先被1除,再累乘,肯定有很多種解法,我下面的代碼雖然通過測試,但是有溢出的隱患

class Solution {
public:
    double Power(double base, int exponent) {
        if(base == 0)
            return 0;
        if(exponent == 0)
            return (double)1;
        double _base =1;
        if(exponent >0)
        {
            for(int i=0;i<exponent;i++)
            _base *=base;
        return _base;
        }
        if(exponent <0)
        {
            base = 1/base;
        }
        exponent = -exponent;
        for(int i=0;i<exponent;i++)
            _base *=base;
        return _base;
    }
};

7.輸入一個整數數組,實現一個函數來調整該數組中數字的順序,使得所有的奇數位於數組的前半部分,所有的偶數位於數組的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。
思路分析:可以設置兩個輔助棧,一個用來裝奇數,另一個用來裝偶數,最終將兩個棧合起來,再替換原來的棧。還有一種做法是類似冒泡算法,前奇後偶就交換。

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        for(int i=0;i<array.size();i++)
        {
            if(array[i]%2 !=0)
            {
                Odd.push_back(array[i]);
            }
            else{
                Eve.push_back(array[i]);
            }
        }
        for(int i=0;i<Eve.size();i++)
        {
            Odd.push_back(Eve[i]);
        }
        for(int i=0;i<array.size();i++)
        {
            array[i] = Odd[i];
        }
    }
private:
    vector<int> Eve;
    vector<int> Odd;
};

8.輸入一個鏈表,輸出該鏈表中倒數第k個結點。
思路:設置兩個指針的,先判斷是輸入參數否符合條件,當第一個指針走到第k個節點位置,讓第二個節點和第一個節點一起走,直到第一個節點到最後一個優先節點,返回第二個節點。
還有一種方法是將鏈表節點按順序壓入棧中,再取出第k個節點。下面是第一種思路的實現。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if(k == 0|| pListHead == nullptr)
       return nullptr;
        
        ListNode* l;
          ListNode* m;
            l = pListHead;
            m = pListHead;
            for(int i=1;i<k;i++)
            {
                if(l->next != nullptr)
                l = l->next;
                else 
                    return nullptr;
            }
        
        while(l->next != nullptr)
        {
            l = l->next;
            m = m->next;
        }
        return m;
       
    }
};

9.輸入兩個單調遞增的鏈表,輸出兩個鏈表合成後的鏈表,當然我們需要合成後的鏈表滿足單調不減規則。

思路分析:先確定頭節點是哪個,設置兩個節點指針,一個用來存頭解點,一個用來記錄之後每個節點,需要注意的一點是,記錄用的節點除了第一次頭節點是用本身來記錄節點,其他都是是用next來記錄,不能用本身來記錄節點,否則會出錯。
在這裏插入圖片描述

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if(pHead1 == nullptr)
            return pHead2;
        if(pHead2 == nullptr)
            return pHead1;
        ListNode* pHd  = nullptr;
        ListNode* pHd2 = nullptr;
        
        while(pHead1 != nullptr && pHead2 != nullptr)
        {
            if(pHead1->val >= pHead2->val)
            {
                if(pHd == nullptr)
                {
                    pHd = pHead2;
                    pHd2 = pHd;
                    pHead2 = pHead2->next;
                }
                else
                {
                 pHd->next = pHead2 ;
                    pHd = pHd ->next;
                pHead2 = pHead2->next;
                }
            }
            else
            {
                if(pHd == nullptr)
                {
                    pHd = pHead1;
                    pHd2 = pHd;
                    pHead1 = pHead1->next;
                }
                else{
                    pHd->next = pHead1 ;
                    pHd = pHd ->next;
                pHead1 = pHead1->next;
                }
                
            }
           
        }
        if(pHead1 == nullptr)
        {
            pHd->next = pHead2;
        }
        else{
            pHd->next = pHead1;
        }
        return pHd2;
    }
    
};

10.輸入一個鏈表,反轉鏈表後,輸出新鏈表的表頭。
思路:用三個指針分別儲存當前指針,前面的一個指針,後面的指針,然後按次序反轉,最後返回節點,下面用的是迭代的方法。

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == nullptr||pHead->next == nullptr)
        {
            return pHead;
    }
            ListNode* head = pHead;
            ListNode* nehead;
            ListNode* prehead = nullptr;
       while(head)
       {    
           nehead = head->next;
           head->next = prehead;
           prehead = head;
           head = nehead;
       }
        
        return prehead;
    }
};

11.輸入兩棵二叉樹A,B,判斷B是不是A的子結構。(ps:我們約定空樹不是任意一個樹的子結構)
思路分析:根據樹的結構,應該用遞歸的形式用前序的方式判斷每個根是否爲B樹的根,如果是調用判斷函數,結果用應該bool值儲存,如果有一個bool值爲真,返回真,全部爲假返回假,由子樹的定義可知,當A的節點爲空且B樹並未空時,返回假,如果B節點爲空返回真,否則進入下一層,得到結果。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    bool HasSubtree(TreeNode* p1, TreeNode* p2)
    {
        if(p1 == nullptr )
            return false;
             
        if( p2 == nullptr)
            return false;
        bool result;
            if(p1->val == p2->val)
            {
                result = _hass(p1,p2);
            }
            if(result == false)
            {
                result = HasSubtree(p1->left,  p2);
            }
       if(result == false)
            {
                result = HasSubtree(p1->right,  p2);
            }
        return result;
    }
    
  
    
    bool _hass(TreeNode* p1, TreeNode* p2)
    {
        if(p1 ==nullptr && p2 == nullptr)
            return true;
        if(p1 == nullptr)
            return false;
        if(p2 == nullptr)
            return true;
        if(p1->val != p2->val)
        return false;
        
        return _hass(p1->left,p2->left)&&_hass(p1->right,p2->right);
        
        
    }
};

12.輸入一個整數,輸出該數二進制表示中1的個數。其中負數用補碼錶示。

思路分析:這道題的關鍵在於負數的補碼裏面的1的個數的計算,可以考慮用位移運算符來計算,要注意的是位移運算符的優先度最小,要加上括號,同時因爲負數的算術左移問題,不能移動輸入的數字,而是要移動用來判斷的變量1,如果與的結果非0,count++。用count記錄,最後輸出

class Solution {
public:
     int  NumberOf1(int n) {
       long long count = 0;
         int flag = 1;
         while(flag)
         {
             if((n & flag) != 0)
             {
                 count++;
             }
             flag = (flag<<1);
         }
         return count;
     }
};

13.輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。

思路分析:這道題的關鍵是平衡二叉樹的性質,可以用中序來對樹的節點進行修改,設置一個節點指針變量pre = nullptr,用來儲存上一個節點,用引用傳遞的方式傳入參數,讓當前的節點的左節點指向pre,判斷pre是否爲空指針,如果不是,pre的右節點指向當前的節點,最後一步,將當前的節點賦給pre,不斷遞歸調用,停止條件爲當前節點爲空。完成後,用循環將最左邊的節點找到,返回。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        if(pRootOfTree == nullptr)
            return nullptr;
        if(pRootOfTree->left == nullptr && pRootOfTree->right == nullptr)
            return pRootOfTree;
        TreeNode* pre = nullptr;
        _convert(pRootOfTree,pre);
        while(pRootOfTree->left)
        {
            pRootOfTree = pRootOfTree->left;
        }
        return pRootOfTree;
    }
    
    void _convert(TreeNode* p,TreeNode*& pre)
    {
        if(p == nullptr)
            return ;
        _convert(p->left,pre);
       p->left = pre;
        if(pre)
             pre->right = p;
        pre = p;
        _convert(p->right,pre);
        
    }
};

14.輸入一個複雜鏈表(每個節點中有節點值,以及兩個指針,一個指向下一個節點,另一個特殊指針指向任意一個節點),返回結果爲複製後複雜鏈表的head。(注意,輸出結果中請不要返回參數中的節點引用,否則判題程序會直接返回空)

思路分析:解決這一題有多種方法,這裏我採用了容易理解的三段法
1.在每個節點後加入一個複製節點。
2.遍歷變長的鏈表,確定random的指向
3.斷開鏈表
在這裏插入圖片描述

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    void Clone1(RandomListNode* p1)
    {
         //複製原始鏈表的任一節點N並創建新節點N',再把N'鏈接到N的後邊
        RandomListNode* p = p1;
        while(p != nullptr)
        {
            RandomListNode* node = new RandomListNode(0);
            node->label = p->label;
        node ->next = p->next;
            node ->random= nullptr;
        p->next = node;
        p = node->next;
        }
    }
     void Clone2(RandomListNode* p1)
     {
     /*如果原始鏈表上的節點N的random指向S,則對應的複製節點N'的random指向S的下一個節點S'*/
         if(p1 == nullptr)
             return ;
         RandomListNode* p = p1;
         RandomListNode* clone = p->next;
         while(p != nullptr)
         {
             if(p->random != nullptr)
         {
             clone->random= p->random->next ;
         }
             p = p->next->next;
             clone = p->next;
         }
     }
    RandomListNode* Clone3(RandomListNode* p1)
    {
     /*把得到的鏈表拆成兩個鏈表,奇數位置上的結點組成原始鏈表,偶數位置上的結點組成複製出來的鏈表*/
        if(p1 == nullptr)
            return p1;
        RandomListNode* phead,*pclone;
        
        phead = pclone = p1->next;
        p1->next = pclone->next;
        p1 = pclone->next;
        while(p1 != nullptr)
        {
           
            pclone->next = p1->next;
            pclone = pclone->next;
            p1->next = pclone->next;
            p1 = p1->next;
        }
        return phead;
        
    }
    
    RandomListNode* Clone(RandomListNode* pHead)
    {
        Clone1(pHead);
        Clone2(pHead);
        return Clone3(pHead);
    }
    
    
};

15.輸入一個字符串,按字典序打印出該字符串中字符的所有排列。例如輸入字符串abc,則打印出由字符a,b,c所能排列出來的所有字符串abc,acb,bac,bca,cab和cba。
思路分析:可以用遞歸法,列三個參數,字符串,vector,固定的字符的下標,通過循環將固定的字符和後面的每個字符交換,當交換到最後一位時,插入vector中,在插入前用find函數檢查是否有重複的字符串,最後的結果再用vector的sort函數排序。

class Solution {
public:
    vector<string> Permutation(string str) {
        vector<string> beg;
        if(str.empty())
        {
            return beg;
        }
        _Permutation(str,beg,0);
        sort(beg.begin(),beg.end());
        return beg;
    }
    
    void _Permutation(string str,vector<string>& beg,int num)
    {
        if(num == str.size()-1)
        {
            if(find(beg.begin(),beg.end(),str) == beg.end())
            {
                beg.push_back(str);
            }
            
        }
        else
        {
         for(int i=num;i<str.size();i++)
         {
             my_swap(str[num],str[i]);
             _Permutation(str,beg,num+1);
             my_swap(str[num],str[i]);
         }
        }
    }
    void my_swap(char &a,char &b)
    {
        char c;
        c =a;
        a = b;
        b = c;
    }
    
};

16.給你一根長度爲n的繩子,請把繩子剪成m段(m、n都是整數,n>1並且m>1),每段繩子的長度記爲k[0],k[1],…,k[m]。請問k[0]xk[1]x…xk[m]可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別爲2、3、3的三段,此時得到的最大乘積是18。
思路:當小於2時,無法分割,爲2時,最大值爲1,爲3時最大值爲2,大於3後 4 = 22
5= 2
3
6=222
可以看到所有的分割段都與2和3有關,只要計算能分割多少2和3,且儘量分割2的情況下,計算乘積合就是最大值

class Solution {
public:
    int cutRope(int number) 
    {
        if(number < 2)
            return 0;
        if(number == 2)
            return 1;
        if(number == 3)
            return 2;
        int num = number/3;
        if(number - 3*num == 1)
            num--;
        int num2 = (number- 3*num)/2;
        return pow(2,num2)*pow(3,num);
    }
};

17.寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。
思路:兩個數相加,可以考慮爲二進制下的運行,分爲三步

  1. 在不計算進位的情況下,計算每個位相加的結果
  2. 計算兩個數的進位結果,如果爲0,就結束,否則重複1.
  3. 輸出結果
    以10進製爲例 9 + 8 個位爲7 十分位爲1 ,在計算10+7結果十位爲1 個位爲7,進位爲0結束運算。
class Solution {
public:
    int Add(int num1, int num2)
    {
        int tem = num1;
        
        while(num2 != 0)
        {
            tem = num1^num2;
            num2 = (num1&num2)<<1;
            num1 = tem;
        }
        return tem;
    }
};

18.請設計一個函數,用來判斷在一個矩陣中是否存在一條包含某字符串所有字符的路徑。路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則該路徑不能再進入該格子。 例如 a b c e s f c s a d e e 矩陣中包含一條字符串"bcced"的路徑,但是矩陣中不包含"abcb"路徑,因爲字符串的第一個字符b佔據了矩陣中的第一行第二個格子之後,路徑不能再次進入該格子。
思路:可以用遞歸解這道題,雖然題中爲一個矩形,但是給出的是一個
指針,所以需要自己控制邊界條件,再進行上下左右的判斷,輸出結果。


class Solution {
public:
    bool hasPath(char* matrix, int rows, int cols, char* str)
    {  
      if(str==NULL||rows<=0||cols<=0)
           return false;
      bool *isOk=new bool[rows*cols]();
      for(int i=0;i<rows;i++)
      {
           for(int j=0;j<cols;j++)
                if(isHsaPath(matrix,rows,cols,str,isOk,i,j))
                   return true;
      }
      return false;
    }
 bool isHsaPath(char *matrix,int rows,int cols,char *str,bool *isOk,int curx,int cury)
 {
      if(*str=='\0')
           return true;
      if(cury==cols)
      {
           curx++;
           cury=0;
      }
      if(cury==-1)
      {
           curx--;
           cury=cols-1;
      }
      if(curx<0||curx>=rows)
           return false;
      if(isOk[curx*cols+cury]||*str!=matrix[curx*cols+cury])
           return false;
      isOk[curx*cols+cury]=true;
      bool sign=isHsaPath(matrix,rows,cols,str+1,isOk,curx-1,cury)
       ||isHsaPath(matrix,rows,cols,str+1,isOk,curx+1,cury)
       ||isHsaPath(matrix,rows,cols,str+1,isOk,curx,cury-1)
       ||isHsaPath(matrix,rows,cols,str+1,isOk,curx,cury+1);
      isOk[curx*cols+cury]=false;
      return sign;
 }
};
  1. 地上有一個m行和n列的方格。一個機器人從座標0,0的格子開始移動,每一次只能向左,右,上,下四個方向移動一格,但是不能進入行座標和列座標的數位之和大於k的格子。 例如,當k爲18時,機器人能夠進入方格(35,37),因爲3+5+3+7 = 18。但是,它不能進入方格(35,38),因爲3+5+3+8 = 19。請問該機器人能夠達到多少個格子?
    思路分析:開始想使用二維數組,發現禁止用變量來當下標,使用一維數組,確定邊界條件,用數組的false和true確定是否走過當前格子,如果格子沒走過合,返回 1+上下左右的返回值。
class Solution {
public:
    int movingCount(int threshold, int rows, int cols)
    {
        if(rows == 0 || cols == 0 || threshold == 0)
        {
            return 0;
        }
        
        bool* m = new bool[rows * cols]; 
        for(int i=0;i<rows*cols;i++)
        {
            m[i] = false;
        }
        return help(0,0,threshold,rows,cols,m);
    }
    
    int help(int i,int j,int threshold, int rows, int cols,bool* m)
    {
        if(i<0||j<0||i>=rows||j>=cols||m[i*cols+j] == true||numSum(i)+numSum(j) > threshold)
        {
            return 0;
        }
        m[i*cols+j] = true;
        return (1+help(i+1,j,threshold,rows,cols,m)+help(i,j+1,threshold,rows,cols,m)+help(i-1,j,threshold,rows,cols,m)+help(i,j-1,threshold,rows,cols,m));
    }
    
    int numSum(int i)
    {
        int index = 0;
       while(i >0)
        {
            index += i %10;
            i /= 10;
        }
        
        return index;
    }
    
    
    
    
};
  1. 請實現一個函數用來匹配包括’.‘和’‘的正則表達式。模式中的字符’.‘表示任意一個字符,而’'表示它前面的字符可以出現任意次(包含0次)。 在本題中,匹配是指字符串的所有字符匹配整個模式。例如,字符串"aaa"與模式"a.a"和"abaca"匹配,但是與"aa.a"和"aba"均不匹配
    思路:首先將傳入的參數分情況討論,
    str爲空 pattern不爲空 不確定
    ,str爲空 pattern爲空 真
    str爲空 pattern不爲空 假
    然後判因爲
    ’表示它前面的字符可以出現任意次,所以再分情況討論一個字符後面是否有*,當沒有時比較簡單,只要看當前字符是否和str的對應位置的字符相同或者爲‘.’返回true否則返回false,當有*時,有兩種情況,噹噹前字符和str的對應位置的字符值相同,分別對跳過當前字符和 ** 或者跳過str的字符,判斷返回值,如果當前字符和str的對應位置的字符值不相同,只要判斷跳過當前字符的值後的字符串是否和str匹配就行了,用遞歸實現。
class Solution {
public:
    bool match(char* str, char* pattern)
    {
          if(*str=='\0' && *pattern == '\0')
              return true;
        if(*str !='\0' && *pattern == '\0')
              return false;
        char * str1 = str;
        char * pat1 = pattern;
       if(*(pat1+1) != '*')
       {
           if(*pat1 == *str1 || *pat1 == '.' && *str != '\0')
              return  match(str1+1,pat1+1);
           else
               return false;
       }
        else
        {
            if(*pat1 == *str1 || *pat1 == '.' && *str != '\0')
                return match(str+1,pattern) || match(str,pattern+2);
            else
                return match(str,pattern+2);
        }
    
    }
   
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章