剑指offer 1-5

二维数组中的查找

题目:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路分为两种:

1.暴力两重遍历,挺好,一遍直接过了
2.根据题目所给出的有序性来快速定位我们想找的那个数,先找到行,再找到列

C++:

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
       if(!array.size())
       {
           return false;    
       }
        int i=0,j=array[0].size()-1;
        while(i<array.size()&&j>=0)
        {
            if(array[i][j]==target)
            {
                return true;
            }else if(array[i][j]<target)//先跟最右上角的比较,如果大的话,向下移。
            {
                i++;
            }else
            {
                j--;  //之后找到这一行,再与这一列的进行比较。
            }
        }
       
        return false;
    }
};

PYTHON:

# -*- coding:utf-8 -*-
class Solution:
    # array 二维列表
    def Find(self, target, array):
        row=len(array)
        j=len(array[0])-1
        i=0
        while(i<row and j>=0):
            if target>array[i][j]:
                i++
            elif target<array[i][j]:
                j--
            else return 'true'
        return 'false'
        # write code here
while True:
    try:
        S=Solution()
        # 字符串转为list
        L=list(eval(raw_input()))
        array=L[1]
        target=L[0]
        print(S.Find(target, array))
    except:
        break

替换空格

请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

思路:

遍历字符串,每到遇到空格时,就将后面的字符向右边移动2个位置,移动完后,再插入%20.
看评论区老哥,有的是新开一个字符串,我感觉挺秒的,具体直接看代码,不难


class Solution {
public:
	void replaceSpace(char *str,int length) {
        char *start =str;
        while(*str!='\0')
        {
            if(*str==' ')
            {
                char *begin = start+length;
                while(begin!=str)
                {
                    *(begin+2)=*begin;
                      begin--;
                }
                *str='%';
                *(str+1)='2';
                *(str+2)='0';
                str+=3;
            }else
            {
                str++;
            }
        }
	}
};
public class Solution {
    public String replaceSpace(StringBuffer str) {
        if(str==null)
        {
            return null;
        }
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<str.length();i++)
        {
              if(str.charAt(i)==' ')
              {
                  sb.append("%");
                  sb.append("2");
                  sb.append("0");
              }else
              {
                   sb.append(str.charAt(i));
              }
        }
        return sb.toString();
    
    }
}

从尾到头打印链表

输入一个链表,按链表从尾到头的顺序返回一个ArrayList。

思路:

从尾到头,这不是栈的性质吗,反转,遍历一遍链表,将指存入栈,再将值,pop出来,就完事了。

class Solution {
public:
    vector<int> printListFromTailToHead(ListNode* head) {
        vector<int> arraylist;
        ListNode* begin = head;
        stack<int> stk;
        while(!begin)
        {
           stk.push(begin->val);
            begin=begin->next;
        }
        while(!stk.empty())
        {
            arraylist.push_back(stk.top());
            stk.pop();
        }
        return arraylist;
        
        
    }
};

重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回

思路:

先找到根节点在,中序遍历的位置,以此来辨认右子树和左子树的位置和数量,得到左子树的前序遍历和中序遍历的列表,得到右子树的前序遍历和中序遍历的列表。

代码:

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {
        int inlen=in.size();
  
            if(inlen==0)
  
                return NULL;
  
            vector<int> left_pre,right_pre,left_in,right_in;
  
            //创建根节点,根节点肯定是前序遍历的第一个数
  
            TreeNode* head=new TreeNode(pre[0]);
  
            //找到中序遍历根节点所在位置,存放于变量gen中
  
            int gen=0;
  
            for(int i=0;i<inlen;i++)
  
            {
  
                if (in[i]==pre[0])
  
                {
  
                    gen=i;
  
                    break;
  
                }
  
            }
  
            //对于中序遍历,根节点左边的节点位于二叉树的左边,根节点右边的节点位于二叉树的右边
  
            //利用上述这点,对二叉树节点进行归并
  
            for(int i=0;i<gen;i++)
  
            {
  
                left_in.push_back(in[i]);
  
                left_pre.push_back(pre[i+1]);//前序第一个为根节点
  
            }
  
            for(int i=gen+1;i<inlen;i++)
  
            {
  
                right_in.push_back(in[i]);
  
                right_pre.push_back(pre[i]);
  
            }
  
            //和shell排序的思想类似,取出前序和中序遍历根节点左边和右边的子树
  
            //递归,再对其进行上述所有步骤,即再区分子树的左、右子子数,直到叶节点
  
           head->left=reConstructBinaryTree(left_pre,left_in);
  
           head->right=reConstructBinaryTree(right_pre,right_in);
  
           return head;
  
        }
    
};

两个栈实现队列

用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

思路

一个栈,时输入的数,会反转,因为先进后出嘛,而当我们有另一个栈时,我们可以将数,再输入进另外一个栈时,那么就可以当成队列来使用了,直接看代码吧。

class Solution
{
public:
    void push(int node) {
        stack1.push(node);
    }

    int pop() {
      int result;
        if(stack2.empty())
        {
         while(!stack1.empty())
       {
            stack2.push(stack1.top());
           stack1.pop();
       }
       }
        
       result=stack2.top();
        stack2.pop();
        return result;
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};
posted @ 2020-02-01 11:08  YenKoc  阅读(115)  评论(0编辑  收藏  举报