剑指offer(一)

一、

题目描述

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
剑指offer(一)_第1张图片

1、vector > array

#include
#include

using namespace std; 

int main()
{
    vector< vector > m(6);//m[i]返回的是第i个向量。同理,mmm6[i][j]返回的是第i个向量中第j个元素  
    for (int i = 0; i < 6; i++)  
    {  
        m[i].resize(2);  //指定向量大小,定义了一个6*2的数组 
    } 
    for (int i = 0; i < 6; i++)  
    {  
            m[i][0]=i;  
            m[i][1]=i+1;  
    }//全部初始化为0 
    for(int i=0;i<6;i++)
	{
	    for(int j=0;j<2;j++)
		{
			cout<

剑指offer(一)_第2张图片

 

容器嵌套容器,获取二维数组的方式。通过这种方式可以为二维数据赋初值。

#include 
#include 

using namespace std;

int main()
{
    vector< vector > test;  //输入n*n的方阵 
    vector v;
    int n,temp;

    cin >> n;
    test.clear();

    //输入
    for (int i = 0; i> temp;
            v.push_back(temp); //插入temp 
        }
        test.push_back(v);//整体插入 v 
    }

    //输出
    for(int i = 0; i < n; i++)
    {
        for(int j = 0;j < n; j++)
        {
            cout << test[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

剑指offer(一)_第3张图片

 2、暴力解法

class Solution 
{
    public:
        bool Find(int target, vector > array) 
        {
           int n,m,x,y;
           n=array.size();//行
           m=array[0].size();//列
           for (int i=0;i

 遍历一遍,全部输出。

时间复杂度(n^2) 

 3、利用矩阵已经从左到右从上到下排好序的特点,从左下角开始,如果比目标值大则上一行,如果比目标值小则向右移动。

class Solution 
{
    public:
        bool Find(int target, vector > array) 
        {
           int n,m,x=0,y;
           n=array.size();//行
           m=array[0].size();//列
           n--;
           
           while(x=0)
           {
               if(target>array[n][x])
               {
                   x++;
               }
               else if(target
class Solution 
{
    public:
        bool Find(int target, vector > array) 
        {
           int n,m,x=0,y;
           n=array.size();//行
           m=array[0].size();//列
           n--;
           
           while(x=0 && target!=array[n][x])
           {
               if(target>array[n][x])
               {
                   x++;
               }
               else if(target

4、剑指offer书中的源程序

 剑指offer(一)_第4张图片

该程序传递的是位置指针,所以需要对位置特别清楚才行。不是下标[a][b],而是连续的a*b的空间。

二、

题目描述

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

剑指offer(一)_第5张图片

 这是定义了一个字符型的变量空间,是char类型,而非string。所以处理起来注意地址位置的判断。

1、

剑指offer(一)_第6张图片

越界的情况。

剑指offer(一)_第7张图片

剑指offer(一)_第8张图片

#include
#include
#include   

using namespace std;

int main()
{
	char a[]="hello world";
	char b[]="hello world";
	//cout<

剑指offer(一)_第9张图片

从加黄的代码可以看出,用常量内存初始化数组时,判断会将地址考虑到内。

2、

替换空格的实际应用

剑指offer(一)_第10张图片

用string方法比较简单,遍历判断,+号连接。

#include
#include
#include   

using namespace std;

string ReplaceSpace(string str)
{
	string s;
	for(int i=0;i

剑指offer(一)_第11张图片

还可以用find函数,string.erase() 和string.insert() 函数。

#include
#include
#include   

using namespace std;

string ReplaceSpace(string str)
{
	int i=0;
	while( (i=str.find(' ',i)) > -1)
	{
		str.erase(i,1);//从i开始,删除一个字符,即删除空格;
		str.insert(i,"%20"); 
	}
	return str;
}

int main()
{
	string str;
	while(getline(cin,str))
	{
		cout<

剑指offer(一)_第12张图片

3、char 地址,并且void 没有返回,所以这是在原地址上修改字符串。

3.1

 剑指offer(一)_第13张图片

class Solution {
public:
	void replaceSpace(char *str,int length) 
    {
       for(int i=0;i=(i+3);j--)
               {
                   *(str+j)=*(str+j-2); //逆序存放
               }
               *(str+i)='%';//空格部分替换
               *(str+i+1)='2';
               *(str+i+2)='0';
           }
       }
    }
};

以上的方法是见一个空格移动一次,重复移动了很多次,时间复杂度太高。  

class Solution {
public:
	void replaceSpace(char *str,int length) 
    {
       for(int i=0;i=(i+3);j--)
               {
                   str[j]=str[j-2]; //逆序存放
               }
               str[i]='%';//空格部分替换
               str[i+1]='2';
               str[i+2]='0';
           }
       }
    }
};

下标的方法。  

3.2

首先就判断出所有的空格,进而判断出替换 后的总长度,再只需一次移动,和替换,完成任务。

class Solution {
public:
	void replaceSpace(char *str,int length) 
    {
       int n=0;
       for(int i=0;i=0;i--)
       {
           if(str[i]!=' ')//添加字符
           {
               str[L]=str[i];
               L--;
           }
           else //替换为%20
            {
               str[L]='0';
               str[L-1]='2';
               str[L-2]='%';
               L=L-3;
             }
        }
    }
};

两个数分别来表示替换前和替换后的下标的方法值得学习。  

三、

题目描述

大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。

n<=39

1、1、2、3、5、8、13、21、34、……

剑指offer(一)_第14张图片

1、递归计算,重复计算很多,但是代码简单

#include

using namespace std;

int Dp(int n)
{
    if(n==1 || n==2)
    {
        return 1;
    }    
    else
    {
        return Dp(n-1)+Dp(n-2);
    }
        
}
    
int Fibonacci(int n) 
{
    return Dp(n);
} 

int main()
{
	int n;
	while(cin>>n)
	{
		cout<

剑指offer(一)_第15张图片

2、牛客中通过不了

class Solution {
public:
    int Dp(int n)
    {
        if(n==1 || n==2)
        {
            return 1;
        }    
        else
        {
            return Dp(n-1)+Dp(n-2);
        }
        
    }
    
    int Fibonacci(int n) 
    {
        return Dp(n);
    }
};

剑指offer(一)_第16张图片

3、使用递推的代码

class Solution {
public:
    int Fibonacci(int n) 
    {
        if(n==0)
            return 0;
        else if(n==1 or n==2)
            return 1;
        int n1=1,n2=1,r=0;
        for(int i=3;i<=n;i++)
        {
            r=n1+n2;
            n1=n2;
            n2=r;
        }
        return r;
    }
};

 

四、

题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
动态规划的典型题目
例如:青蛙跳到5级,其上一步只能由3级跳到5级,或者4级跳到5级。所以跳到5级的方法就是跳到3级和跳到4级方法之和。
可以找出递归关系。f(n)=f(n-1)+f(n-2);
class Solution {
public:
    int Num[10000]={0};
    int jumpFloor(int number) 
    {
        Num[1]=1;
        Num[2]=2;
        for(int i=3;i<=number;i++)
        {
            Num[i]=Num[i-1]+Num[i-2];
        }
        return Num[number];
    }
};

一定注意题目是求多少种方法,而不是求上了多少次台阶,所以递归关系中不用加1。

 

五、

题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
class Solution {
public:
    int Num[10000]={0};
    int jumpFloorII(int number) 
    {
        Num[1]=1;
        Num[2]=2;
        for(int i=3;i<=number;i++)
        {
            for(int j=0;j

递推关系发生变化f(n)=f(n-1)+f(n-2)+...+f(1)+1;  

 

六、

题目描述

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
剑指offer(一)_第17张图片
看到一个很不错的图
剑指offer(一)_第18张图片

可以看出,n是在n-1和n-2的基础上进行扩展,所以递推关系还是f(n)=f(n-1)+f(n-2);

class Solution {
public:
    int Num[10000]={0};
    int rectCover(int number)
    {
        Num[1]=1;
        Num[2]=2;
        for(int i=3;i<=number;i++)
        {
            Num[i]=Num[i-1]+Num[i-2];
        }
        return Num[number];
    }
};

 

七、

  


 

  

  

  

  

 

 

 

 

 

  

  

 

 

 

 

 

 

 

 

  

转载于:https://www.cnblogs.com/ruo-li-suo-yi/p/9005729.html

你可能感兴趣的:(剑指offer(一))