剑指offer 第二天

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

                             1  2  8   9

                             2  4  9  12

                             4  7  10 13

                             6  8  11  15

分析:二维数组如上所示:从左到右是由小到大,从上到下也是从小到大。比如我们要查找的数字是6,那么我们从右上角的数字9看起。9比6大,那么第四列是不可能存在6的,第四列排除。在看第三列的第一个数字,8比6大,第三列排除。
第二列的2比6小,所以6只存在于2的下面。依次类推,直到找到结束

public class TwoArray {
	public boolean research(int [][]a ,int number) {
		boolean flag =false;
		if(a!=null&&a.length!=0) {
			int rows=a.length;
			int cols=a[0].length;
			
			int row=0;//当前的行数,索引从0开始,所以row=0
			int col=cols-1;//当前的列数,索引从0开始,所以是列数-1
			//假如矩阵的维数是4*4,则最右上角的数字索引为(0,3),最左下角的数字为(3,0)
			while(row<=rows-1&&col>=0) {
				if (a[row][col]==number) {
					flag=true;
					System.out.println(flag);
					break;
				
				}else if(a[row][col]>number) {
					col--;//如果索引的数大于要查找的数,那肯定存在于之前的列,所以列数自减
				}else {
					row++;//如果索引的数小于要查找的数,那肯定存在于之后的行,所以行数自增
				}
				
			}
			
		}
		
		return flag;
		
	}
	public static void main(String[] args) {
		int array[][] = { { 1, 2, 8, 9 }, { 2, 4, 9, 12 }, { 4, 7, 10, 13 }, { 6, 8, 11, 15 } };
       TwoArray a=new TwoArray();
       a.research(array, 1);
      

	}
}

第四题:请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy”,则输出”We%20are%20happy”.

方法一:利用Stringbuffer类,将原来的字符串逐个复制进Stringbuffer数组,当扫到空格时,往里添加字符串“20%”。具体实现如下:

import java.util.ArrayList;

public class String1 {

	public boolean demo(String a) {
		boolean flag=false;
		if(a==null&&a.length()==0) {//应该想到的异常状态
			return flag;
		}
		StringBuffer b=new StringBuffer();//String类定义的对象不可修改,但StringBuffer类时专为字符串设计的缓存类,其可以更改。
		for(int i=0;i<a.length();i++) {
			if(a.charAt(i)==' ') {//通过charAt方法将字符串内容逐个提取
				b.append("%20");//如遍历到空格,则往StringBuffer数组中添加20%
			}else {
				b.append(a.charAt(i));//否则将原来字符串内容逐个添加到StringBuffer数组中。
			}
			flag=true;
			
			
		}
		System.out.println(b.toString());
		return flag;
}
	public static void main(String[] args) {
		String1 a=new String1();
		a.demo("we are happy");
	}
}

方法2:我们先遍历一次字符串,这样就能够统计出字符串中空格的总数,并可以计算出替换之后字符串的总长度。每替换一个空格,长度增加2,因此替换以后的字符串的长度等于原来的长度加上2乘以空格的数目,我们还是以前面的字符串”We are happy”为例,“We are happy”这个字符串的长度是14,里面有两个空格,因此替换之后的字符串的长度为18

我们从字符串的后面开始复制和替换。首先准备两个指针,P1和P2. P1指向原始字符串的末尾,而P2指向替换之后的字符串的末尾。接下来我们向前移动指针P1,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。此时字符串包含如下图b所示,灰色阴影的区域是做了字符拷贝的区域。碰到第一个空格之后,把P1向前移动一格,在P2之前插入字符串”%20“,由于”%20“的长度为3,同时也要把P2向前移动3格如图所示。

我们接着向前复制,直到碰到第二个空格(d)所示。和上一次一样,我们再把P1向前移动1格,并把P2向前移动3格插入”%20“(如图e),此时P1,P2指向同一个位置,表明所有的空格都已经替换完毕。

从上面的分析我们可以看出,所有的字符都只复制一次,因此这个算法的时间效率是O(n),比第一个思路要快。
在这里插入图片描述

public class String2 {
public boolean domo(String a) {
	boolean flag=false;
	int c=0;
	
	char [] b1=a.toCharArray();//先将之前字符串转化成字符数组
	for(int i=0;i<b1.length;i++) {
		if(b1[i]==' ') {
			c++;          //字符串中空格的个数
		}
	}
	char [] b2=new char[a.length()+c*2];//由于是要将原来的空格替换成20%,所以新数组的长度是原来数组长度+空格个数*2
	for (int i=0;i<b1.length;i++) {
		b2[i]=b1[i];           //将之前数组内容全部复制到新数组,之后的操作在新数组上执行
	}
	int d1=b1.length-1;         //索引从0开始,所以索引d1为原来数组长度-1
	int d2=b2.length-1;         //索引从0开始,所以索引d2为新数组长度-1
	while(d1>=0&&d2>=d1) {
		if(b2[d1]==' ') {     //遍历到空格后,从后往前逐个赋值“%”“2”“0”
			b2[d2--]='0';
			b2[d2--]='2';
			b2[d2--]='%';
		}else {
			b2[d2--]=b2[d1];//没有遍历到空格,索引d1的值和d2对换
		}
		d1--;
	}
	
	System.out.println(new String(b2));
	flag=true;
	System.out.println(flag);
	return flag;
}
public static void main(String[] args) {
	String2 a=new String2();
	a.domo("i love you");
}
}

参考博文:请点击

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值