ArrayAndString(数组和字符串)

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/370643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

position 的属性值

理论上来说&#xff0c;全部 position 的取值有8个 包括&#xff1a;position&#xff1a;static | relative | absolute | fixed | sticky | initial | inherit | unset 其中最常用的是 static 、relative、absolute、fixed 和 sticky initial、inherit、unset 是css的关键…

mysql数据库应用的权限层级_MySQL数据库的用户权限管理

嗨&#xff01;各位小伙伴今天翻了一下历史记录MySQL 数据库还有点内容今天开始我们就来补上吧~用户权限管理伙伴们要知道&#xff0c;在数据库方面有两个方向。一个是数据库管理员(Database Administrator)简称DBA&#xff0c;一个是数据库开发工程师(Database Developer)&…

linux i2c adapter 增加设备_Linux驱动之I2C驱动架构

一、Linux的I2C体系结构主要由三部分组成&#xff1a;(1) I2C核心提供I2C控制器和设备驱动的注册和注销方法&#xff0c;I2C通信方法&#xff0c;与适配器无关的代码以及探测设备等。(2) I2C控制器驱动(适配器)(3) I2C设备驱动二、重要的结构体i2c_adapter//i2c控制器(适配器)i…

Alpha-end

前言 失心疯病源10团队代码管理github个人感悟 肝不动了&#xff0c;肝不动了。明天如果见不到我&#xff0c;不要太想我。站立会议 队名&#xff1a;PMS530雨勤&#xff08;组长&#xff09; 今天完成了那些任务 熬夜肝代码代码签入github明天的计划 肝到凌晨还剩下哪些任务 团…

避免写慢SQL

最近在整理数据库中的慢SQL&#xff0c;同时也查询了相关资料。记录一下&#xff0c;要学会使用执行计划来分析SQL。 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一&#xff0c;而且这是被MySQL的数据库引擎处理的。当有很多相同…

为什么子孙后代会讨厌使用java.util.Stack

在我用无意义的重言式杀死你之前&#xff0c;这是要点 如果您的应用程序接近实时&#xff0c;或者将代码发送到Mars&#xff0c;则需要保留Java中默认的Stack实现。 根据LinkedList编写您自己的版本。 同样&#xff0c;如果您的应用程序是关键任务&#xff0c;并且希望堆栈由…

play 连接mysql_Play framework 2.x 连接mysql | 学步园

笔者所使用的系统为64位 windows7。本文假设java1.5版本以上环境已经搭好&#xff0c;play 框架已经下载至本地。首先我们创建一个项目。命令行进入play的目录命令&#xff1a;play new demo再次输入项目名字输入2 选择java项目创建完成界面OK&#xff0c;一个play框架下的java…

rpm -e --nodeps_微课 | rpm的思维导图

前导课程&#xff1a;微课 | rpm的查询、升级与卸载命令本次微课将演示使用xmind绘制rpm思维导图的过程&#xff0c;包括视频文字&#xff0c;大约需要你10分钟。另外&#xff0c;文末还有一则IT冷笑话&#xff0c;学习之余、会心一笑:)这个思维导图将包含以下内容&#xff1a;…

border-sizing属性详解和应用

box-sizing用于更改用于计算元素宽度和高度的默认的 CSS 盒子模型。它有content-box、border-box和inherit三种取值。inherit指的是从父元素继承box-sizing表现形式&#xff0c;不再冗赘。1. 属性讲解 content-box 默认值&#xff0c;也是css2.1中的盒子模型。在计算 width和…

Couchbase:使用Twitter和Java创建大型数据集

在播放/演示Couchbase或任何其他NoSQL引擎时&#xff0c;创建大型数据集的一种简单方法是将Twitter feed注入到数据库中。 对于这个小应用程序&#xff0c;我正在使用&#xff1a; Couchbase Server 2.0服务器 Couchbase Java SDK &#xff08;将由Maven安装&#xff09; T…

西门子scl语言编程手册_西门子SCL编程PEEK指令讲解

单词“peek”在英语中表示“偷看&#xff0c;瞥一眼”&#xff0c;在计算机编程中表示“读取数据”。在西门子SCL编程中&#xff0c;PEEK指令可以用来读取输入缓存区(I)、输出缓存区(Q)、位存储区(M)及数据块(DB)中的数据&#xff0c;常用作间接寻址。今天这篇文章&#xff0c;…

Guava的Collections2:过滤和转换Java集合

Groovy的便利之一是能够通过Groovy的闭包支持轻松地对集合执行过滤和转换操作。 Guava将对集合的过滤和转换引入标准Java&#xff0c;这是本文的主题。 Guava的Collections2类具有两个公共方法&#xff0c;这两个方法都是静态的。 方法filter&#xff08;Collection&#xff0…

钉钉机器人怎么设置自动回复_项目部署成功后触发钉钉机器人发送消息提醒——入门配置...

钉钉建好一个群打开群设置, 找到群机器人添加一个你想要的机器人可以使用自定义自定义机器人可以自定义头像,名字,生成一个webhook(https post的请求地址)到这里, 钉钉机器人设置好了,接下来我们对照文档进行配置https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq/XAzBI -…

mysql加锁语法_MySql 加锁问题

1、设置非自动提交 set autocommit0; 这时候 for update才会起作用2、一般用法 set autocommit0; for update(加锁) ; commit/rollback; set autocommit1;首先看一下&#xff0c;set autocommit0 后&#xff0c;执行哪些语句会自动加锁&#xff0c;加的是什么锁&#xff1f…

td过长,将固定宽度table撑开

解决办法&#xff1a; 在table上加上样式: table{table-layout:fixed;word-break:break-all} table-layout:fixed tablle的列宽由表格宽度和列宽设定。 word-break:break-all 允许在单词内换行。 正常情况下&#xff1a; table表格中td过长&#xff1a; 加上样式之后&#…

Android几秒后自动关闭dialog

代码改变世界 Android几秒后自动关闭dialog AlertDialog.Builder builder new AlertDialog.Builder(v.getContext());builder.setTitle("发送成功&#xff01;");builder.setMessage("2秒后自动关闭&#xff01;");builder.setCancelable(true);final Ale…

控制元素的div属性

1、需求分析 改变元素的宽、高、颜色、显示、重置等属性。 2、技术分析 基础的css、html、js 3、详细分析 如图&#xff0c;单击按钮&#xff0c;改变元素属性: 3.1 HTML部分 根据视图不难发现&#xff0c;内容分两大不分:按钮栏和效果图&#xff0c;所以设置两个div。 <…

使用JMeter和Yourkit进行REST / HTTP服务的性能分析

我的上一篇文章描述了如何使用JMeter完成异步REST / HTTP服务的压力测试或负载测试。 但是&#xff0c;运行这样的测试通常表明被测系统不能很好地应对不断增加的负载。 现在的问题是如何找到瓶颈&#xff1f; 深入研究代码以检测可疑部分可能是另一种选择。 但是考虑到潜在的…

java中间件_90%的Java程序员,都扛不住这波消息中间件的面试四连炮!

概述大家平时也有用到一些消息中间件(MQ)&#xff0c;但是对其理解可能仅停留在会使用API能实现生产消息、消费消息就完事了。对MQ更加深入的问题&#xff0c;可能很多人没怎么思考过。比如&#xff0c;你跳槽面试时&#xff0c;如果面试官看到你简历上写了&#xff0c;熟练掌握…

python 取array并集_Python内置数据结构原理与性能简易分析

ins ngladc文末左下方阅读原文指向了本人博客链接&#xff0c;不含广告。参考资料中的相关链接&#xff0c;可以在博客文章的最下方获取。推荐苹果手机用户使用浅色模式观看。前言 对于一些算法题&#xff0c;可以使用Python自带的内置函数解决。但很多时候用就用了&#xff0c…