1.实现一个算法,确定一个字符串的所有字符是否全都不同。假使不允许使用额外的数据结构,又该怎么处理?

public class UniqueChars {public static void main(String[] args) {// TODO Auto-generated method stubString string = "abcdefgfedcba";System.out.print(isUniqueChars(string));}public static boolean isUniqueChars(String str) {if (str.length() > 256) {return false;}boolean[] char_set = new boolean[256];for (int i = 0; i < str.length(); i++) {int val = str.charAt(i);if (char_set[val]) {return false;}char_set[val] = true;}return true;}}

View Code

注意:向面试官确认上面的字符串是ASCII字符串还是Unicode字符串。若不是ASCII字符串需扩大存储空间,但其余逻辑不变。

这里假定是ASCII字符串。首先做一个优化,若字符串长度大于字母表中的字符个数,就直接返回false。毕竟,若字母表只有256个字符,字符串里就不可能有280个各不相同的字符。

然后构建一个布尔值的数组,索引值i对应的标记指示该字符串是否含有字母表第i个字符。若这个字符第二次出现,则立即返回false。时间复杂度o(n),空间复杂度o(1)。

若不允许使用额外的数据结构:

(1)将字符串中的每一个字符与其余字符进行比较。时间复杂度为o(n2),空间复杂度o(1)。

public class UniqueChars {public static void main(String[] args) {// TODO Auto-generated method stubString string = "abcdefgfedcba";System.out.print(isUniqueChars(string));}public static boolean isUniqueChars(String str) {if (str.length() > 256) {return false;}for(int i = 0; i < str.length(); i++) {for(int j = i + 1; j < str.length(); j++) {if(str.charAt(i) == str.charAt(j)) return false;}}return true;}
}

View Code

(2)若允许修改输入字符串,可以在o(nlogn)的时间里对字符串排序,然后线性检查其中有无相邻字符完全相同的情况。

2.用Java实现void reverse(char* str)函数,即反转一个null结尾的字符串。

package ArrayAndString;public class Reverse {public static void main(String[] args) {// TODO Auto-generated method stubString string = "abcdefg";System.out.println(reverseString2(string));}//最简单的方法public static String reverseString(String iniString) {// write code hereStringBuffer tmp = new StringBuffer(iniString);tmp = tmp.reverse();return tmp.toString();}//最常用的方法public static String reverseString2(String iniString) { char[] array = iniString.toCharArray(); String reverse = "";  //注意这是空串,不是nullfor (int i = array.length - 1; i >= 0; i--) { reverse += array[i];}return reverse; } }

View Code

3.给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

解法一:对字符串排序后进行比较,若它们拥有相同顺序的字符,即互为变位词。

import java.util.*;public class IsAnagram {public static void main(String[] args) {// TODO Auto-generated method stubString string1 = "aceg";String string2 = "cega";System.out.println(permutation(string1, string2));    }public static String sort(String s) {char[] content = s.toCharArray();Arrays.sort(content);return new String(content);}public static boolean permutation(String s, String t) {if (s.length() != t.length()) {return false;}return sort(s).equals(sort(t));}}

View Code

解法二:利用变位词的定义--组成两个单词的字符数相同,遍历字母表,计算每个字符出现的次数,然后比较这两个数组。

public class IsAnagram {public static void main(String[] args) {// TODO Auto-generated method stubString string1 = "aceg";String string2 = "cega";System.out.println(permutation(string1, string2));    }public static boolean permutation(String s, String t) {if (s.length() != t.length()) {return false;}int[] letters = new int[256];char[] s_array = s.toCharArray();for (char c : s_array) {letters[c]++;}for (int i = 0; i < t.length(); i++) {int c = (int) t.charAt(i);if (--letters[c] < 0) {return false;}}return true;}}

View Code

注意:向面试官确认 变位词是否区分大小写 以及 是否要考虑空白字符。

这里假定变位词比较区分大小写,空白也要考虑在内,是ASCII字符串。首先做一个优化,比较两个字符串的长度,只要长度不同就不可能是变位词。

4.编写一个方法,将字符串中的空格全部替换为“%20”。假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的“真实”长度。(注:用Java实现的话,请使用字符数组实现,以便直接在数组上操作。)

思路:进行两次扫描。第一次扫描先数出字符串中有多少空格,从而算出最终的字符串有多长。第二次扫描真正开始反向编辑字符串,检测到空格则将%20复制到下一个位置,若不是空白,就复制原先的字符。

public class ReplaceString {public static void main(String[] args) {// TODO Auto-generated method stubString str = "abc d e f";char[] arr = new char[str.length() + 3 * 2 + 1];for (int i = 0; i < str.length(); i++) {arr[i] = str.charAt(i);}replaceSpaces(arr, str.length());    System.out.println("\"" + charArrayToString(arr) + "\"");}public static String charArrayToString(char[] array) {StringBuilder buffer = new StringBuilder(array.length);for (char c : array) {if (c == 0) {break;}buffer.append(c);}return buffer.toString();}public static void replaceSpaces(char[] str, int length) {int spaceCount = 0;int index = 0; int i = 0;for (i = 0; i < length; i++) {if (str[i] == ' ') {spaceCount++;}}index = length + spaceCount * 2;str[index] = '\0';for (i = length - 1; i >= 0; i--) {if (str[i] == ' ') {str[index - 1] = '0';str[index - 2] = '2';str[index - 3] = '%';index = index - 3;} else {str[index - 1] = str[i];index--;}}}}

View Code

注意:处理字符串操作问题时,常见做法是从字符串尾部开始编辑,从后往前反向操作。因为字符串尾部有额外的缓冲,可以直接修改,不必担心会复写原有数据。

5.利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变成a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。

public class StringZipper {public static void main(String[] args) {// TODO Auto-generated method stubString str = "aabccccaaa";System.out.println(compressString(str));}public static String compressString(String str) {if (str.length() == 0) {return str;}int flag = 0;int count = 1;StringBuffer sb = new StringBuffer();char last = str.charAt(0);for (int i = 1; i < str.length(); i++) {if (str.charAt(i) == last) {count++;flag = 1;} else {sb.append(last);sb.append(count);last = str.charAt(i);count = 1;}}sb.append(last);sb.append(count);if (flag == 0 || sb.length() >= str.length()) {return str;} else {return sb.toString();}}}

View Code

注意:使用flag变量记录字符串中是否有重复字符。若最终flag=0说明字符串中无重复字符,返回原字符串。时间复杂度和空间复杂度都为o(N)。

6.给定一幅由N*N矩阵表示的图像,其中每个像素的大小为4字节,编写一个方法,将图像旋转90度。不占用额外内存空间能否做到?

二维数组a[n][n]顺时针旋转90度,找规律如下:

当n=1时,不动。当n=2时,有:a[0][0] = a[1][0]  a[1][0] = a[1][1]  a[1][1] = a[0][1]  a[0][1] = a[0][0]  初步总结规律为:a[i][j] = a[n-1-j][i]

当n=3,4,5,……时也是满足的。到这里,如果不考虑空间复杂度,只需要再构建一个二维数组b[n][n],利用公式b[i][j] = a[n-1-j][i]就可以解决。代码如下:

public void rotate(int[][] matrix) {int n = matrix.length;int[][] m = new int[n][n];for(int row=0;row<n;row++){for(int col=0;col<n;col++){m[row][col] = matrix[n-1-col][row];}}//再赋值回matrix,注意java是形参是引用传递for(int row=0;row<n;row++){for(int col=0;col<n;col++){matrix[row][col] = m[row][col];}}}

View Code

但是题目要求不占用额外空间,应该怎么旋转?接着上面的分析,以n=3为例:把焦点放在一个元素的旋转上,可以看出要在原数组中旋转,在不丢失数据的情况下,每个值的旋转会“波及”4个数,以1为例波及到了1,3,7,9,每个数旋转要不丢失数据就要考虑如何让这4个数都得以保留。前边总结了规律a[i][j] = a[n-1-j][i],分析每组被波及的数,我们可以得出这里波及了的4个数其实就是a[i][j]  a[n-1-j][i]  a[n-1-i][n-1-j]  a[n-1-(n-1-j)][n-1-i]=a[j][n-1-i] 所以这里需要引入一个临时变量temp就可以解决这4个数的顺时针交换,如:

int temp = matrix[i][j];

matrix[i][j] = matrix[n-1-j][i];

matrix[n-1-j][i] = matrix[n-1-i][n-1-j];

matrix[n-1-i][n-1-j] = matrix[j][n-1-i];

matrix[j][n-1-i] = temp;

把焦点放在一个元素上,数交换的问题解决了。那么现在把焦点回到整个二维数组上来,每个数的旋转会波及4个数,相当于用上面的方法,每旋转一个数,就把一组的4个数都旋转了,

所以现在的问题就是如何才能完整的把所有的数都旋转90度且不会多旋转,继续分析:

n=1时,不需旋转。

n=2时,只需要完成1(a[0][0])的旋转,就完成了整个数组的旋转。

n=3时,需要完成1,2(a[0][0],a[0][1])的旋转,就完成了整个数组的旋转。

n=4时,需要完成1,2,3,6(a[0][0至3],a[1][1])的旋转。

n=5时,需要完成(a[0][0至4],a[1][1至2])的旋转。

大致可以总结出这么一个规律:对于要旋转的数a[i][j]满足,i<n/2 且 i<=j<n-1-i,至此问题终于解决。

public class Rotate {public static void main(String[] args) {// TODO Auto-generated method stubint[][] arr = {{1,2,3}, {4,5,6}, {7,8,9}};int length = arr.length;int[][] arr1 = transform(arr, length);for(int i = 0; i < length; ++i) {for(int j = 0; j < length; ++j) {System.out.print(arr1[i][j]+" ");}}}public static int[][] transform(int[][]matrix, int n) {int limit = n / 2;for (int i = 0; i < limit; i++) {for(int j = i; j < n - i - 1; j++) {int temp = matrix[i][j];matrix[i][j] = matrix[n-1-j][i];matrix[n-1-j][i] = matrix[n-1-i][n-1-j];matrix[n-1-i][n-1-j] = matrix[j][n-1-i];matrix[j][n-1-i] = temp;}}return matrix;}}

View Code

算法的时间复杂度为o(N的平方),已经是最优做法。

7.编写一个算法,若M*N矩阵中某个元素位0,则将其所在的行与列清零。

public class ClearZeros {public static void main(String[] args) {// TODO Auto-generated method stubint[][] arr = {{1,2,0}, {4,5,6}, {7,8,9}};int[][] arr1 = setZeros(arr);for(int i = 0; i < arr.length; ++i) {for(int j = 0; j < arr[0].length; ++j) {System.out.print(arr1[i][j]+" ");}}}public static int[][] setZeros(int[][] matrix) {boolean[] row = new boolean[matrix.length];boolean[] column = new boolean[matrix[0].length];for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {if (matrix[i][j] == 0) {row[i] = true;column[j] = true;}}}for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {if (row[i] || column[j]) {matrix[i][j] = 0;}}}return matrix;}}

View Code

注意:不能在第一次遍历整个矩阵时,发现值为零的元素就直接将其所在的行与列清零,这样的话最后整个矩阵的所有元素都会变为零。要新建一个矩阵标记零元素的位置,在第二次遍历矩阵时将零元素所在的行与列清零。而且只需记录哪行和哪列有零元素即可,无须记录零元素的确切位置。

8.假定有一个方法isSubstring,可检查一个单词是否为其他字符串的子串。给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成,要求只能调用一次isSubstring。(比如,waterbottle是erbottlewat旋转后的字符串)。

public class IsRotation {public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println(isRotation("abc","abc"));}public static boolean isSubstring(String str1,String str2){if(str1.contains(str2) || str2.contains(str1)) {return true;}return false;}public static boolean isRotation(String str1,String str2){if(str1.length() != str2.length()) {return false;}String sum = str1 + str1;return isSubstring(sum, str2);}}

View Code

注意:假定s2由s1旋转而成,那么将s1切分成x和y,就会满足xy=s1和yx=s2。不论x和y之间的分割点在哪,yx都肯定是xyxy的子串,也即s2总是s1s1的子串。直接调用isSubstring(s1s1,s2)即可。

转载于:https://www.cnblogs.com/struggleli/p/7815584.html

ArrayAndString(数组和字符串)相关推荐

  1. 数组、字符串对象、Math对象

    数组的介绍 数组介绍 概念: 就是将若干个数据以一定的顺序放在一起的一个集合体,整体上就称之为"数组".数组就是一列数据的有序排列的集合. 定义形式: var arr1 = new ...

  2. python中numpy数组和字符串互转(互转后数据完全一致)

    python中numpy数组和字符串互转(互转后数据完全一致) 代码: import numpy as np # 创建数组arr arr = np.array([ -1.8264365 , -0.63 ...

  3. C#中字节数组与字符串的来回转换

    C#中字节数组与字符串的来回转换会遇到一个奇怪的问题.这个问题是在做网络传送文件时遇到的. 问题如下: 就是把件流形成的字节数组转成字符串发送,对端接收到过后把字符串还原成字节数组然后形成文件流. 这 ...

  4. 如何将Swift数组转换为字符串?

    本文翻译自:How do I convert a Swift Array to a String? I know how to programmatically do it, but I'm sure ...

  5. 如何将零终止的字节数组转换为字符串?

    本文翻译自:How to convert a zero-terminated byte array to string? I need to read [100]byte to transfer a ...

  6. php 长短字符串转换,将php的数组按照字符串长短进行排序

    将php的数组按照字符串长短进行排序 如果想在PHP编程中对数组进行操作,可以用到有关的PHP数组函数来达到自己的需求.今天我们将为大家介绍的时候有关PHP数组按字符串长短排序的实现方法. 深入剖析P ...

  7. python3 字符串转数组 数组转字符串 切片操作

    1.数组转字符串 #方法1 arr = ['a','b'] str1 = ''.join(arr)#方法2 arr = [1,2,3] #str = ''.join(str(i) for i in a ...

  8. java数组与字符串互转

    String str="1,2,3,4,5"; String s[]=str.split(",");如果是 "字符串数组" 转 " ...

  9. java字符串拆分成数组_用Java实现JVM第八章《数组和字符串》

    小傅哥 | https://bugstack.cn 沉淀.分享.成长,专注于原创专题案例,以最易学习编程的方式分享知识,让自己和他人都能有所收获.目前已完成的专题有:Netty4.x实战专题案例.用J ...

  10. Jackson:数组json字符串转对象集合(List)的两种方式

    首先,创建个实体类Person import java.util.List;public class Person {private String name;private Integer age;p ...

最新文章

  1. 这或许是东半球分析十大排序算法最好的一篇文章
  2. 【赠书】如何构建企业级的推荐系统?这本书值得一看
  3. 数组实用类:Arrays
  4. 编写一个程序,实现将存放在AX和DX中的32位数据循环右移二进制数的4位。(DX存放高字节内容,AX存放低字节内容)
  5. 定义整型数组_C语言基础-数组怎么用
  6. matlab中如何表示线积分,MATLAB - 复杂的线/路径积分
  7. Java高并发编程详解系列-类加载
  8. spring cloud gateway 之限流篇
  9. 一个ContentProvider的典型结构分析
  10. 625某电商网站数据库宕机故障解决实录(上)
  11. gis坐标北京54转WGS84坐标系
  12. Third season fifth episode,Phoebe‘s brother Frank came to see her
  13. Teamviwer操作(请激活复选框,证明是本人操作解决办法)
  14. ElementUI table表格数据html格式解析
  15. WSTMart 分销说明,三级分销与返利
  16. 12款浏览器兼容性测试工具推荐
  17. 关于浏览器方向的大厂面试题
  18. 车载电子电器做E-mark认证的费用是多少?
  19. 【翻译】在Windows上直接查询SRV方式的地址
  20. mongodb基本语法及操作(增删改查)

热门文章

  1. url重写(urlrewrite)的一些系统变量
  2. NOI 练手题 图像旋转翻转变换
  3. FTP服务器的搭建与安全配置
  4. do语句转化为局部函数一例
  5. echo回声不能用了_已懂得用电子分频器,为何不继续加个效果器让音响效果更好?...
  6. 可执行程序加载到内存的过程
  7. 眼图观测实验报告_眼图观察测量实验
  8. 配置编译win7+VS2017+opencv4.0.1+contrib4.0.1
  9. 嵌入式开发有年龄限制吗_什么?!考教资有年龄限制了?2020年我还能考吗?...
  10. 对着爬虫网页HTML学习Python正则表达式re