您的位置:首页 > Web前端

《剑指offer》——二维数组中的查找 和 替换空格

2017-01-28 11:45 190 查看

《剑指offer》——二维数组中的查找 和 替换空格

2017年1月28日记

一、数据结构

链表和树是面试中出现频率最高的数据结构。栈是一个与递归紧密相连的数据结构,同样队列也与广度优先遍历算法密切相关。

数组的内存是连续的,需要事先指定数组的容量,因此,数组的空间效率不是很好,但数组可以在O(1)的时间内读/写任何元素,因此时间效率很高。为了解决空间效率不高的问题,设计了动态数组。

二、面试题3:二维数组中的查找

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

例如,下面就是符合条件的二维数组,如果在这个数组中查找数字7,则返回true;如果查找数字5,则返回false.

1 2 8 9

2 4 9 12

4 7 10 13

6 8 11 15


解决方案是:首先选取数组中右上角的数字。如果该数字等于要查找的数字,查找过程结束;如果该数字大于要查找的数字,剔除这个数字所在的列;如果该数字小于要查找的数字,剔除这个数字所在的行。也就是说,如果要查找的数字不在数组的右上角,则每一次都在数组的查找范围中剔除一行或者一列,这样每一步都可以缩小查找的范围,直到找到要查找的数字,或者查找范围为空。

同时,我们也可以每一次选择数组左下角的数字,但我们不能选择左上角或者右下角,以左上角为例,最初数字1小于7,但我们不能剔除1所在的行,也不能剔除1所在的列,这样我们就无法缩小查找范围。

三、面试题4:替换空格

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

时间复杂度为O(n^2)的算法,不足以拿到offer

最容易想到的解法,从头到尾遍历字符串,没遇到一个空格就替换成”%20”,同时把字符串的其他所有元素向后移动两位。

假设字符串的长度为n,对于每个空格字符,需要移动后面的O(n)个字符,因此对含有O(n)个空格字符的字符串而言,总的时间效率为O(n^2)。

时间复杂度为O(n)的算法,搞定Offer就靠它了

我们可以先遍历一遍字符串,统计出总共有多少空格,并由此计算出替换后的字符串的总长度。每替换一个空格,字符串长度增加2。

我们从字符串的后面开始复制和替换,准备两个指针P1和P2,P1指向原字符串的末尾,P2指向替换后的字符串的末尾。接下来移动P1,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。碰到空格之后,把p1向前移动一个为止跳过该空格,同时在p2之前插入字符串“%20”,由于“%20”的长度为3,同时也要把P2向前移动3个位置。

同理,继续移动,向前复制。直到P1和P2指向同一个位置,表明所有的空格都已经替换完毕。

这个解决方案可以看出,所有的字符只需要复制(移动)一次,因此这个算法的时间效率为O(n),比第一个思路要快。

举一反三:合并两个数组时(包括字符串)时,如果从前往后复制每个字符需要移动字符很多次,那么我们可以考虑从后往前复制,这样就能减少移动的次数,从而提高效率。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: