劍指offer二刷2

刪除鏈表中重復(fù)的結(jié)點(diǎn)

我的:

//方法1:
  ListNode* deleteDuplication(ListNode* pHead)
    {
       ListNode* rHead=new ListNode(0);
         ListNode* rtemp=rHead;
        ListNode* temp=pHead;
        if(pHead==NULL||pHead->next==NULL) return pHead;
        int value = NULL;
        while(temp->next!=NULL){
            if(temp->val == temp->next->val){
                value = temp->val;
            }else{
                if(value==NULL||temp->val != value){
                   rtemp->next = temp;
                   rtemp = rtemp->next;
                }
            }
              temp = temp->next;
        }
        if(temp->val!=value){
             rtemp->next = temp;
            rtemp = rtemp->next;
        }
        rtemp->next = NULL;
        return rHead->next;
    }
//方法2:遞歸
 ListNode* deleteDuplication(ListNode* pHead)
    {
        if (pHead==NULL)
            return NULL;
        if (pHead!=NULL && pHead->next==NULL)
            return pHead;
                 
        ListNode* current;
         
        if ( pHead->next->val==pHead->val){
            current=pHead->next->next; 
            while (current != NULL && current->val==pHead->val)
                current=current->next;
            return deleteDuplication(current);                      
        }
         
        else {
            current=pHead->next;
            pHead->next=deleteDuplication(current);
            return pHead;
        }     
    }
//方法3:非遞歸的代碼:
1. 首先添加一個(gè)頭節(jié)點(diǎn),以方便碰到第一個(gè),第二個(gè)節(jié)點(diǎn)就相同的情況
2.設(shè)置 pre ,last 指針, pre指針指向當(dāng)前確定不重復(fù)的那個(gè)節(jié)點(diǎn),而last指針相當(dāng)于工作指針,一直往后面搜索。

if (pHead==null || pHead.next==null){return pHead;}
ListNode Head = new ListNode(0);
Head.next = pHead;
ListNode pre  = Head;
ListNode last = Head.next;
while (last!=null){
    if(last.next!=null && last.val == last.next.val){
        // 找到最后的一個(gè)相同節(jié)點(diǎn)
        while (last.next!=null && last.val == last.next.val){
            last = last.next;
        }
        pre.next = last.next;
        last = last.next;
    }else{
        pre = pre.next;
        last = last.next;
    }
}
return Head.next;

//方法4:
 ListNode* deleteDuplication(ListNode* pHead)
    {
          if(pHead==NULL||pHead->next==NULL) return pHead;
          else
          {
              //新建一個(gè)節(jié)點(diǎn),防止頭結(jié)點(diǎn)要被刪除
              ListNode* newHead=new ListNode(-1);
              newHead->next=pHead;
              ListNode* pre=newHead;
              ListNode* p=pHead;
              ListNode* next=NULL;
              while(p!=NULL && p->next!=NULL)
              {
                  next=p->next;
                  if(p->val==next->val)//如果當(dāng)前節(jié)點(diǎn)的值和下一個(gè)節(jié)點(diǎn)的值相等
                  {
                      while(next!=NULL && next->val==p->val)//向后重復(fù)查找
                          next=next->next;
                    pre->next=next;//指針賦值,就相當(dāng)于刪除
                    p=next;
                  }
                  else//如果當(dāng)前節(jié)點(diǎn)和下一個(gè)節(jié)點(diǎn)值不等,則向后移動(dòng)一位
                  {
                      pre=p;
                      p=p->next;
                  }
              }
           return newHead->next;//返回頭結(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)
               
          }
    }


劍指:方法3,4一樣

二叉樹的下一個(gè)結(jié)點(diǎn)

我的:

//方法1:
int flag = false;
    TreeLinkNode* result=NULL;
   void zhong(TreeLinkNode* root, TreeLinkNode* pNode){
        if(root==NULL) return;
        if(root->left!=NULL) zhong(root->left,pNode);
        if(flag){
            result = root;
            flag = false;
            return ;
        }
        if(root == pNode){
            flag = true;
        }
        if(root->right!=NULL) zhong(root->right,pNode);
   }
   TreeLinkNode* GetNext(TreeLinkNode* pNode)
    {
        TreeLinkNode* root = pNode;
        while(root->next!=NULL){
            root = root->next;
        }
        zhong(root,pNode);
        return result;
    }
//方法2:

//分析二叉樹的下一個(gè)節(jié)點(diǎn),一共有以下情況:
//1.二叉樹為空,則返回空;
//2.節(jié)點(diǎn)右孩子存在,則設(shè)置一個(gè)指針從該節(jié)點(diǎn)的右孩子出發(fā),一直沿著指向左子結(jié)點(diǎn)的指針找到的葉子節(jié)點(diǎn)即為下一個(gè)節(jié)點(diǎn);
//3.節(jié)點(diǎn)不是根節(jié)點(diǎn)。如果該節(jié)點(diǎn)是其父節(jié)點(diǎn)的左孩子,則返回父節(jié)點(diǎn);否則繼續(xù)向上遍歷其父節(jié)點(diǎn)的父節(jié)點(diǎn),重復(fù)之前的判斷,返回結(jié)果。
classSolution{
 public:
     TreeLinkNode* GetNext(TreeLinkNode* pNode)
     {
         if (pNode == NULL)
             returnNULL;
         if (pNode->right != NULL)
         {
             pNode = pNode->right;
             while (pNode->left != NULL)
                 pNode = pNode->left;
             returnpNode;
         }
         while (pNode->next != NULL)
         {
             TreeLinkNode *proot = pNode->next;
             if (proot->left == pNode)
                 returnproot;
             pNode = pNode->next;
         }
         returnNULL;
     }
 };

PS:方法2:
思路:首先知道中序遍歷的規(guī)則是:左根右,然后作圖

image

結(jié)合圖,我們可發(fā)現(xiàn)分成兩大類:1、有右子樹的,那么下個(gè)結(jié)點(diǎn)就是右子樹最左邊的點(diǎn);(eg:D,B,E,A,C,G) 2、沒(méi)有右子樹的,也可以分成兩類,a)是父節(jié)點(diǎn)左孩子(eg:N,I,L) ,那么父節(jié)點(diǎn)就是下一個(gè)節(jié)點(diǎn) ; b)是父節(jié)點(diǎn)的右孩子(eg:H,J,K,M)找他的父節(jié)點(diǎn)的父節(jié)點(diǎn)的父節(jié)點(diǎn)...直到當(dāng)前結(jié)點(diǎn)是其父節(jié)點(diǎn)的左孩子位置。如果沒(méi)有eg:M,那么他就是尾節(jié)點(diǎn)。

劍指:方法2

對(duì)稱的二叉樹

我的:

//方法1:
 bool judge(TreeNode* lRoot, TreeNode* rRoot){
        if(lRoot==NULL&&rRoot==NULL) return true;
         if(lRoot==NULL&&rRoot!=NULL) return false;
        if(lRoot!=NULL&&rRoot==NULL) return false;
        if(lRoot->val != rRoot->val) return false;
        return judge(lRoot->left,rRoot->right)&&judge(lRoot->right,rRoot->left);
    }
   bool isSymmetrical(TreeNode* pRoot)
    {
        if(pRoot==NULL) return true;
        return judge(pRoot->left,pRoot->right);
    }

//方法2:
代碼很簡(jiǎn)單,關(guān)鍵還是知道怎么樣才能判斷一個(gè)
二叉樹是否對(duì)稱,只要采用前序、中序、后序、層次遍歷等任何一種遍歷方法,分為先左后右和先
右后左兩種方法,只要兩次結(jié)果相等就說(shuō)明這棵樹是一顆對(duì)稱二叉樹。
迭代版本
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(root==NULL) return true;
        queue<TreeNode*> q1,q2;
        TreeNode *left,*right;
        q1.push(root->left);
        q2.push(root->right);
        while(!q1.empty() and !q2.empty())
        {
            left = q1.front();
            q1.pop();
            right = q2.front();
            q2.pop();
            //兩邊都是空
            if(NULL==left && NULL==right)
                continue;
            //只有一邊是空
            if(NULL==left||NULL==right)
                return false;
             if (left->val != right->val)
                return false;
            q1.push(left->left);
            q1.push(left->right);
            q2.push(right->right);
            q2.push(right->left);
        }
         
        return true;
         
    }
};
//方法3:
/*
      * DFS使用stack來(lái)保存成對(duì)的節(jié)點(diǎn)

     * 1.出棧的時(shí)候也是成對(duì)成對(duì)的 , 

                1.若都為空,繼續(xù); 

                2.一個(gè)為空,返回false; 

                3.不為空,比較當(dāng)前值,值不等,返回false; 
     * 2.確定入棧順序,每次入棧都是成對(duì)成對(duì)的,如left.left, right.right ;left.rigth,right.left
      */
boolean isSymmetricalDFS(TreeNode pRoot)
    {
        if(pRoot == null) return true;
        Stack<TreeNode> s = new Stack<>();
        s.push(pRoot.left);
        s.push(pRoot.right);
        while(!s.empty()) {
            TreeNode right = s.pop();//成對(duì)取出
            TreeNode left = s.pop();
            if(left == null && right == null) continue;
            if(left == null || right == null) return false;
            if(left.val != right.val) return false;
            //成對(duì)插入
            s.push(left.left);
            s.push(right.right);
            s.push(left.right);
            s.push(right.left);
        }
        return true;
    }
  /*
      * BFS使用Queue來(lái)保存成對(duì)的節(jié)點(diǎn),代碼和上面極其相似

     * 1.出隊(duì)的時(shí)候也是成對(duì)成對(duì)的  


               1.若都為空,繼續(xù); 

                2.一個(gè)為空,返回false; 

                3.不為空,比較當(dāng)前值,值不等,返回false; 
     * 2.確定入隊(duì)順序,每次入隊(duì)都是成對(duì)成對(duì)的,如left.left, right.right ;left.rigth,right.left
      */
boolean isSymmetricalBFS(TreeNode pRoot)
    {
        if(pRoot == null) return true;
        Queue<TreeNode> s = new LinkedList<>();
        s.offer(pRoot.left);
        s.offer(pRoot.right);
        while(!s.isEmpty()) {
            TreeNode right = s.poll();//成對(duì)取出
            TreeNode left = s.poll();
            if(left == null && right == null) continue;
            if(left == null || right == null) return false;
            if(left.val != right.val) return false;
            //成對(duì)插入
            s.offer(left.left);
            s.offer(right.right);
            s.offer(left.right);
            s.offer(right.left);
        }
        return true;
    }

劍指:方法1

按之字形順序打印二叉樹

我的:

//方法1:先遍歷后打印
  vector<vector<int> > Print(TreeNode* pRoot) {
          vector<vector<int> > result;
         if(pRoot==NULL) return result;
         queue<TreeNode*> nodes;
         nodes.push(pRoot);
         bool flag = true;
         while(!nodes.empty()){
            vector<int> temp;
            int le = nodes.size();
            for(int i = 0;i<le;i++){
                TreeNode* node = nodes.front();
                nodes.pop();
                temp.push_back(node->val);
                if(node->left!=NULL) nodes.push(node->left);
                if(node->right!=NULL) nodes.push(node->right);
            }
            result.push_back(temp);
         }
         for(int i = 0;i<result.size();i++){
            if(i%2==1) reverse(result[i].begin(),result[i].end());
         }
         return result;
    }
//方法2:stack來(lái)保存逆序
  vector<vector<int> > Print(TreeNode* pRoot) {
         bool flag = true;
         queue<TreeNode> le;
          vector<vector<int> > result;
        if(pRoot==NULL) return result;
         le.push(*pRoot);
         while(!le.empty()){
            vector<int> r;
            stack<int> ri;
            for(int i =0,n=le.size();i<n;i++){
               TreeNode temp = le.front();
                if(flag){
                    r.push_back(temp.val);
                }else{
                    ri.push(temp.val);
                }
                le.pop();
                if(temp.left!=NULL) le.push(*temp.left);
                if(temp.right!=NULL) le.push(*temp.right);
            }
            while(!ri.empty()){
                TreeNode temp = ri.top();
                r.push_back(temp.val);
                ri.pop();
            }
            result.push_back(r);
            flag = !flag;
         }
        return result;
    }
//方法3:
public static ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        int layer = 1;
        //s1存奇數(shù)層節(jié)點(diǎn)
        Stack<TreeNode> s1 = new Stack<TreeNode>();
        s1.push(pRoot);
        //s2存偶數(shù)層節(jié)點(diǎn)
        Stack<TreeNode> s2 = new Stack<TreeNode>();
         
        ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
         
        while (!s1.empty() || !s2.empty()) {
            if (layer%2 != 0) { 
                ArrayList<Integer> temp = new ArrayList<Integer>(); 
                while (!s1.empty()) {
                    TreeNode node = s1.pop();
                    if(node != null) {
                        temp.add(node.val);
                        System.out.print(node.val + " ");
                        s2.push(node.left);
                        s2.push(node.right);
                    }
                }
                if (!temp.isEmpty()) {
                    list.add(temp);
                    layer++;
                    System.out.println();
                }
            } else {
                ArrayList<Integer> temp = new ArrayList<Integer>();
                while (!s2.empty()) {
                    TreeNode node = s2.pop();
                    if(node != null) {
                        temp.add(node.val);
                        System.out.print(node.val + " ");
                        s1.push(node.right);
                        s1.push(node.left);
                    }
                }
                if (!temp.isEmpty()) {
                    list.add(temp);
                    layer++;
                    System.out.println();
                }
            }
        }
        return list;
    }

劍指:方法3

把二叉樹打印成多行

我的:

vector<vector<int> > Print(TreeNode* pRoot) {
         vector<vector<int> > result;
         if(pRoot==NULL) return result;
         queue<TreeNode*> nodes;
         nodes.push(pRoot);
         while(!nodes.empty()){
            vector<int> temp;
            int le = nodes.size();
            for(int i = 0;i<le;i++){
                TreeNode* node = nodes.front();
                nodes.pop();
                temp.push_back(node->val);
                if(node->left!=NULL) nodes.push(node->left);
                if(node->right!=NULL) nodes.push(node->right);
            }
            result.push_back(temp);
         }
         return result;
    }
//方法2:遞歸BFS
//用遞歸做的
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> list = new ArrayList<>();
        depth(pRoot, 1, list);
        return list;
    }
     
    private void depth(TreeNode root, int depth, ArrayList<ArrayList<Integer>> list) {
        if(root == null) return;
        if(depth > list.size()) 
            list.add(new ArrayList<Integer>());
        list.get(depth -1).add(root.val);
         
        depth(root.left, depth + 1, list);
        depth(root.right, depth + 1, list);
    }
}

劍指:一樣

序列化二叉樹

我的:不會(huì)

//方法1:

string result="";
       void xian(TreeNode *root){
           if(root==NULL) result=result+"#!";
           else{
                char temp = root->val+'0';
                result=result+to_string(root->val)+'!';
                xian(root->left);
                xian(root->right);
           }
       }
       char* Serialize(TreeNode *root) {
             if(root==NULL) return NULL;
             xian(root);
                char *ret = new char[result.length() + 1];
            int i;
            for(i = 0; i < result.length(); i++){
                ret[i] = result[i];
            }
            ret[i] = '\0';
            return ret;           
// strcpy(ret, result.c_str());
        }
    TreeNode* Deserialize(char *&str) {
        if(str == NULL) return NULL;
        TreeNode* node = NULL;
        if(*str!='#'){
           int temp = 0;
           while(*str!='!'){
                temp = 10*temp+int(*str-'0');
               str++;
           }
            str++;
           node = new TreeNode(temp);
           node->left = Deserialize(str);
           node->right = Deserialize(str);
        }else str+=2;
        return node;
    }

PS:
序列化二叉樹:把一棵二叉樹按照某種遍歷方式的結(jié)果以某種格式保存為字符串。需要注意的是,序列化二叉樹的過(guò)程中,如果遇到空節(jié)點(diǎn),需要以某種符號(hào)(這里用#)表示。以下圖二叉樹為例,序列化二叉樹時(shí),需要將空節(jié)點(diǎn)也存入字符串中。
反序列化二叉樹:根據(jù)某種遍歷順序得到的序列化字符串,重構(gòu)二叉樹。
劍指:
一樣

二叉搜索樹的第k個(gè)結(jié)點(diǎn)

我的:

//方法1:
 int flag=0;
       TreeNode* result = NULL;
       void zhong(TreeNode *root, int k ){
           if(root!=NULL);
           {
                if(root->left!=NULL)zhong(root->left, k);
                if(++flag==k){
                    result = root;
                }
                if(root->right!=NULL)zhong(root->right,k);
           }
       }
    TreeNode* KthNode(TreeNode* pRoot, int k)
    {
        if(pRoot== NULL) return NULL;
        zhong(pRoot,k);
        return result;
    }

PS:中序遍歷,非遞歸

   void zhong(TreeNode *root){
        stack<TreeNode*> temp;
        while (root != NULL || ! temp.empty()) {
            while (root != NULL) {
                temp.push(root);
                root = root->left;
            }
            root = temp.top();
            temp.pop();
           cout<<root->val<<endl;
            root = root->right;
        }
       }

劍指:遞歸中序

數(shù)據(jù)流中的中位數(shù)

我的:

//方法1:
priority_queue<int, vector<int>, less<int> > large;
   priority_queue<int, vector<int>, greater<int> > small;
   int count = 0;
    void Insert(int num)
    {
        count++;
        large.push(num);
        int lsize = large.size();
        int ssize = small.size();
        if(lsize-ssize>1){
            int temp = large.top();
            large.pop();
            small.push(temp);
        }
       if(!large.empty()&&!small.empty()&&large.top()>small.top()){
             int temp = large.top();
               large.pop();
            int temp2 = small.top();
              small.pop();
                large.push(temp2);
                small.push(temp);
        }
    }
    double GetMedian()
    {
        if(!large.empty()){
             if(count%2==0){
                return (large.top()+small.top())/2.0;
            }else return large.top();
        }
        return NULL;
    }

//方法2:

劍指:一樣

class Solution {
private:
        vector<int> min;
        vector<int> max;
public:
        void Insert(int num)
        {
           if(((min.size()+max.size())&1)==0)//偶數(shù)時(shí) ,放入最小堆 
           {
              if(max.size()>0 && num<max[0])
              {
                // push_heap (_First, _Last),要先在容器中加入數(shù)據(jù),再調(diào)用push_heap ()
                 max.push_back(num);//先將元素壓入容器
                 push_heap(max.begin(),max.end(),less<int>());//調(diào)整最大堆 
                 num=max[0];//取出最大堆的最大值 
                 //pop_heap(_First, _Last),要先調(diào)用pop_heap()再在容器中刪除數(shù)據(jù)
                 pop_heap(max.begin(),max.end(),less<int>());//刪除最大堆的最大值 
                 max.pop_back(); //在容器中刪除 
              }
              min.push_back(num);//壓入最小堆 
              push_heap(min.begin(),min.end(),greater<int>());//調(diào)整最小堆 
           }
           else//奇數(shù)時(shí)候,放入最大堆
           {
              if(min.size()>0 && num>min[0])
              {
                // push_heap (_First, _Last),要先在容器中加入數(shù)據(jù),再調(diào)用push_heap ()
                 min.push_back(num);//先壓入最小堆 
                 push_heap(min.begin(),min.end(),greater<int>());//調(diào)整最小堆 
                 num=min[0];//得到最小堆的最小值(堆頂) 
                 //pop_heap(_First, _Last),要先調(diào)用pop_heap()再在容器中刪除數(shù)據(jù)
                 pop_heap(min.begin(),min.end(),greater<int>());//刪除最小堆的最大值 
                 min.pop_back(); //在容器中刪除 
              }
              max.push_back(num);//壓入數(shù)字 
              push_heap(max.begin(),max.end(),less<int>());//調(diào)整最大堆 
           }    
        }
        /*獲取中位數(shù)*/      
        double GetMedian()
        {
            int si敏感詞.size()+max.size();
            if(size<=0) //沒(méi)有元素,拋出異常 
                return 0;//throw exception("No numbers are available");
            if((size&1)==0)//偶數(shù)時(shí),去平均 
                return ((double)(max[0]+min[0])/2);
            else//奇數(shù),去最小堆,因?yàn)樽钚《褦?shù)據(jù)保持和最大堆一樣多,或者比最大堆多1個(gè) 
                return min[0];
        }
};

滑動(dòng)窗口的最大值

我的:

 vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        int le = num.size();
        int flag = -1;
        int ma = INT_MIN;
         vector<int> result;
           if(size==0) return result;
        for(int i = 0;i<le-size+1;i++){
            if(flag<i){
                flag = i;
                ma = num[i];
                for(int j = i+1;j<i+size;j++){
                    if(num[j]>ma){
                        flag = j;
                        ma = num[j];
                    }
                }
            }else{
                if(num[i+size-1]>num[flag]){
                     flag = i+size-1;
                     ma = num[flag];
                }
            }
            result.push_back(ma);
        }
        return result;

    }
//方法2:雙端隊(duì)列
//引用馬客(Mark)的解題思路,馬客沒(méi)加注釋,我用自己的理解加下注釋,希望對(duì)你們有用,
//如有錯(cuò)誤,見(jiàn)諒,我會(huì)及時(shí)修改。
//deque s中存儲(chǔ)的是num的下標(biāo)
class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> res;
        deque<int> s;
        for(unsigned int i=0;i<num.size();++i){
            while(s.size() && num[s.back()]<=num[i])//從后面依次彈出隊(duì)列中比當(dāng)前num值小的元素,同時(shí)也能保證隊(duì)列首元素為當(dāng)前窗口最大值下標(biāo)
                s.pop_back();
            while(s.size() && i-s.front()+1>size)//當(dāng)當(dāng)前窗口移出隊(duì)首元素所在的位置,即隊(duì)首元素坐標(biāo)對(duì)應(yīng)的num不在窗口中,需要彈出
                s.pop_front();
            s.push_back(i);//把每次滑動(dòng)的num下標(biāo)加入隊(duì)列
            if(size&&i+1>=size)//當(dāng)滑動(dòng)窗口首地址i大于等于size時(shí)才開始寫入窗口最大值
                res.push_back(num[s.front()]);
        }
        return res;
    }
//方法3:雙端
 //時(shí)間復(fù)雜度o(n),空間復(fù)雜度為o(n)
    /*思路就是采用雙端隊(duì)列,隊(duì)列中的頭節(jié)點(diǎn)保存的數(shù)據(jù)比后面的要大。
      比如當(dāng)前假如的數(shù)據(jù)比隊(duì)尾的數(shù)字大,說(shuō)明當(dāng)前這個(gè)數(shù)字最起碼在從現(xiàn)在起到后面的過(guò)程中可能是最大值
      ,而之前隊(duì)尾的數(shù)字不可能最大了,所以要?jiǎng)h除隊(duì)尾元素。
      此外,還要判斷隊(duì)頭的元素是否超過(guò)size長(zhǎng)度,由于存儲(chǔ)的是下標(biāo),所以可以計(jì)算得到;
      特別說(shuō)明,我們?cè)陔p端隊(duì)列中保存的數(shù)字是傳入的向量的下標(biāo);
    */
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> vec;
        if(num.size()<=0 || num.size()<size ||size<=0) return vec;//處理特殊情況
        deque<int> dq;
        //處理前size個(gè)數(shù)據(jù),因?yàn)檫@個(gè)時(shí)候不需要輸出最大值;
        for(unsigned int i=0;i<size;i++)
        {
 //假如當(dāng)前的元素比隊(duì)列隊(duì)尾的元素大,說(shuō)明之前加入的這些元素不可能是最大值了。因?yàn)楫?dāng)前的這個(gè)數(shù)字比之前加入隊(duì)列的更晚
            while(!dq.empty()&&num[i]>=num[dq.back()])
                dq.pop_back();//彈出比當(dāng)前小的元素下標(biāo)
            dq.push_back(i);//隊(duì)尾壓入當(dāng)前下標(biāo)
        }
        //處理size往后的元素,這時(shí)候需要輸出滑動(dòng)窗口的最大值
        for(unsigned int i=size;i<num.size();i++)
        {
            vec.push_back(num[dq.front()]);
            while(!dq.empty()&&num[i]>=num[dq.back()])
                dq.pop_back();
            if(!dq.empty() && dq.front()<=(int)(i-size))//判斷隊(duì)頭的下標(biāo)是否超出size大小,如果超過(guò),要?jiǎng)h除隊(duì)頭元素
                dq.pop_front();//刪除隊(duì)頭元素
            dq.push_back(i);//將當(dāng)前下標(biāo)壓入隊(duì)尾,因?yàn)榭赡茉谖磥?lái)是最大值
        }
        vec.push_back(num[dq.front()]);//最后還要壓入一次
        return vec;
    }

劍指:方法2,下標(biāo),每次加入尾部,刪除小于尾部的,頭判斷是不是過(guò)期

矩陣中的路徑

我的:

//方法1:回溯
bool judge(char* matrix, int nrows, int ncols, int rows, int cols,char* str, vector<int>& flag){
        if(*str=='\0') return true;
        if(nrows<0||nrows>(rows-1)||ncols<0||ncols>(cols-1)||flag[nrows*cols+ncols]==1) return false;
        if(matrix[nrows*cols+ncols] == *str){
            flag[nrows*cols+ncols]=1;
            bool result =
            judge(matrix, nrows-1,ncols,rows,cols,str+1,flag)||
            judge(matrix, nrows+1,ncols,rows,cols,str+1,flag)||
            judge(matrix, nrows,ncols-1,rows,cols,str+1,flag)||
            judge(matrix, nrows,ncols+1,rows,cols,str+1,flag);
            flag[nrows*cols+ncols]=0;
            return result;
        }else return false;
    }
  bool hasPath(char* matrix, int rows, int cols, char* str)
    {
        if(*str=='\0'||*matrix=='\0') return false;
           vector<int> flag(rows*cols, 0);
        int count = 0 ;
        while(*(matrix+count)!='\0'){
            if(*str == *(matrix+count)){
                if(judge(matrix, count/cols,count%cols,rows,cols,str,flag))
                    return true;
            }
            count++;
        }
        return false;
    }
//方法2:

PS:幾種初始化,和傳入形式,達(dá)到修改原值:

int flag[] = new int[matrix.length];  int [] flag
 bool *isOk=new bool[rows*cols]();  bool *isOk,
 vector<bool> used(strlen(matrix),false);  vector<bool>& used
bool *flag=new bool[rows*cols];  bool* flag
 bool *flag=new bool[rows*cols];
        memset(flag,0,rows*cols);
bool* flag

還是沒(méi)搞明白為什么狀態(tài)要改回來(lái),不然永久置1了?為什么我測(cè)試還是沒(méi)問(wèn)題。。。。我的測(cè)試有問(wèn)題:
用例:
"ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS",5,8,"SGGFIECVAASABCEHJIGQEM"

可以看出有無(wú)恢復(fù)的區(qū)別

劍指:

class Solution {
public:
    bool hasPath(char* matrix, int rows, int cols, char* str) {
        bool res = 0;
        bool *flag=new bool[rows*cols];
        memset(flag,0,rows*cols);
        for (int i = 0;i<rows;++i) {
            for (int j = 0;j<cols;++j) {
                //bool *flag = (bool *)calloc(rows*cols, 1);
                res = dfs(matrix, rows, cols, i, j, flag, str);//1
                if (res == true)
                    return res;
            }
        }
        delete[] flag;
        return res;
    }
    bool dfs(char* matrix, int rows, int cols, int i, int j, bool* flag, char* str) {
        if (*str == '\0')
            return true;
        if(i<0||i>=rows||j<0||j>=cols)
            return false;
        if (*(flag+i*cols + j) == 1 || (*(flag+i*cols + j) == 0 && *(matrix + i*cols + j) != *str)) 
            return false;
        else {
            *(flag+i*cols + j) = 1;
            bool res=dfs(matrix, rows, cols, i, j - 1, flag, str + 1)//左
                ||dfs(matrix, rows, cols, i, j + 1, flag, str+1)//右
                ||dfs(matrix, rows, cols, i - 1, j, flag, str+1)//上
                ||dfs(matrix, rows, cols, i + 1, j, flag, str+1);//下
            if(res==0)
                *(flag+i*cols + j)=0;//這樣從1處開始進(jìn)入的DFS即使沒(méi)找到路徑,但是flag最后全部置為0
            return res;
        }
    }

機(jī)器人的運(yùn)動(dòng)范圍

我的:

//方法1:
  int mysum(int x, int y){
      int sum = 0;
      while(x!=0){
        sum=sum+x%10;
        x=x/10;
      }
      while(y!=0){
        sum=sum+y%10;
        y=y/10;
      }
      return sum;
    }
    void judge(int nrows, int ncols, int rows, int cols,int& count, int k,  vector<int>& flag){
        if(nrows<0||nrows>(rows-1)||ncols<0||ncols>(cols-1)||flag[nrows*cols+ncols]==1||mysum(nrows, ncols)>k) return ;
        count++;
        flag[nrows*cols+ncols]=1;
        judge(nrows,ncols+1,rows,cols,count,k,flag);
        judge(nrows,ncols-1,rows,cols,count,k,flag);
        judge(nrows+1,ncols,rows,cols,count,k,flag);
        judge(nrows-1,ncols,rows,cols,count,k,flag);
    }
     int movingCount(int threshold, int rows, int cols)
    {
        if(threshold<0||rows<0||cols<0) return 0;
        int count = 0;
        vector<int> flag(rows*cols,0);
        judge(0, 0, rows, cols,count, threshold, flag);
        return count;
    }
//方法2:

劍指:

   int movingCount(int threshold, int rows, int cols)
    {
        bool* flag=new bool[rows*cols];
        for(int i=0;i<rows*cols;i++)
            flag[i]=false;
        int count=moving(threshold,rows,cols,0,0,flag);//從(0,0)坐標(biāo)開始訪問(wèn);
        delete[] flag;
        return count;
    }
    //計(jì)算最大移動(dòng)位置
    int moving(int threshold,int rows,int cols,int i,int j,bool* flag)
    {
        int count=0;
        if(check(threshold,rows,cols,i,j,flag))
        {
            flag[i*cols+j]=true;
            //標(biāo)記訪問(wèn)過(guò),這個(gè)標(biāo)志flag不需要回溯,因?yàn)橹灰辉L問(wèn)過(guò)即可。
           //因?yàn)槿绻茉L問(wèn),訪問(wèn)過(guò)會(huì)加1.不能訪問(wèn),也會(huì)標(biāo)記下訪問(wèn)過(guò)。
            count=1+moving(threshold,rows,cols,i-1,j,flag)
                   +moving(threshold,rows,cols,i,j-1,flag)
                   +moving(threshold,rows,cols,i+1,j,flag)
                   +moving(threshold,rows,cols,i,j+1,flag);
        }
        return count;
    }
    //檢查當(dāng)前位置是否可以訪問(wèn)
    bool check(int threshold,int rows,int cols,int i,int j,bool* flag)
    {
        if(i>=0 && i<rows && j>=0 && j<cols 
            && getSum(i)+getSum(j)<=threshold 
            && flag[i*cols+j]==false)
           return true;
        return false;
    }
    //計(jì)算位置的數(shù)值
    int getSum(int number)
    {
        int sum=0;
        while(number>0)
        {
            sum+=number%10;
            number/=10;
        }
        return sum;
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容