来自面试金典,只记录思路这些(博主最近时间紧,还是只像你仍代码吧。。。
1.1字符互异
思路一:双循环,O(n^2)
import java.util.*; public class Different { public boolean checkDifferent(String iniString) { for (int i=0;i<iniString.length()-1;i++) { char tmp=iniString.charAt(i); for (int j=i+1;j<iniString.length();j++) { while (tmp==iniString.charAt(j)) return false; } } return true; } }
思路二:boolean[256] +ASCII码,做标记
boolean[] index=new boolean[256]; for (int i=0;i<str.length();i++) { int val=str.charAt(i); if (index[val]){ return false; } index[val]=true; } return true;
1.2 字符反转
无额外开销和无新数据结构;
stringbuffer的反转可以直接做,或者直接赋值就好;
import java.util.*; public class Reverse { public String reverseString(String iniString) { if(iniString.length()<=1) return iniString; StringBuffer rev=new StringBuffer(); for (int i=iniString.length()-1;i>=0;i--) { rev.append(iniString.charAt(i)); } return rev.toString(); // StringBuffer shit=new StringBuffer(iniString); //return shit.reverse().toString(); } }
1.3 乱序同构
题目描述
给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。这里规定大小写为不同字符,且考虑字符串重点空格。
给定一个string stringA和一个string stringB,请返回一个bool,代表两串是否重新排列后可相同。保证两串的长度都小于等于5000。
测试样例:
"This is nowcoder","is This nowcoder"
返回:true
"Here you are","Are you here"
返回:false
思路一:双循环,就把两个读到数组中,然后把2排列成1一模一样的情况
import java.util.*; public class Same { public boolean checkSam(String stringA, String stringB) { if (stringA.length()!=stringB.length()) return false; char[] dataA=stringA.toCharArray(); char[] dataB=stringB.toCharArray(); for (int i=0;i<stringA.length();i++) { int set=1; for (int j=i;j<stringB.length();j++) { if (dataA[i]==dataB[j]) { char tmp=dataB[j]; dataB[j]=dataB[i]; dataB[i]=tmp; set=0; } if (j==(stringA.length()-1)&&set==1) { return false; } } } return true; } }
思路二:ASCII码,记录每个字符出现次数;
细节:依然是输入控制,看长度是否相等;
1.4 空格替换
"Mr John Smith”,13
返回:"Mr%20John%20Smith"
”Hello World”,12
返回:”Hello%20%20World”
直接做吧,或者讲究一点的就先算出有多少个空格,然后规定好长度;
import java.util.*; public class Replacement { public String replaceSpace(String iniString, int length) { char[] data=iniString.toCharArray(); char[] rt=new char[length*3]; int rtIndex=0; for (int i=0;i<length;i++) { if (data[i]==‘ ‘) { rt[rtIndex]=‘%‘;rtIndex++; rt[rtIndex]=‘2‘;rtIndex++; rt[rtIndex]=‘0‘;rtIndex++; }else { rt[rtIndex]=data[i]; rtIndex++; } } String sb=new String(rt); return sb.trim(); } }
细节:String sb=new String(rt);数组与字符串;字符串长度截取;
1.5 基本字符串压缩
利用字符重复出现的次数,编写一个方法,实现基本的字符串压缩功能。比如,字符串“aabcccccaaa”经压缩会变成“a2b1c5a3”。若压缩后的字符串没有变短,则返回原先的字符串。
给定一个string iniString为待压缩的串(长度小于等于10000),保证串内字符均由大小写英文字母组成,返回一个string,为所求的压缩后或未变化的串。
测试样例
"aabcccccaaa"
返回:"a2b1c5a3"
"welcometonowcoderrrrr"
返回:"welcometonowcoderrrrr"
基本思路:快慢指针
import java.util.*; public class Zipper { public String zipString(String iniString) { StringBuffer res=new StringBuffer(); res.append(iniString.charAt(0)); // res.append(1); int index=0; int count=1; int len=iniString.length(); char c=iniString.charAt(0); for (int i=1;i<len;i++) { if (iniString.charAt(i)==c) { count++; //}else if(index>=iniString.length()){ // return iniString; }else{ res.append(count); res.append(iniString.charAt(i)); count=1; c=iniString.charAt(i); index=index+2; } } res.append(count); return (index<len)?res.toString():iniString; //return res.toString(); } }
不用count的写法
import java.util.*; public class Zipper { public String zipString(String iniString) { if(iniString.length()<=2) return iniString; StringBuffer zip=new StringBuffer(); int slow=0; //int count=0; for (int i=1;i<iniString.length();i++) { char val=iniString.charAt(slow); if (iniString.charAt(i)!=val){ zip.append(val); zip.append(i-slow); slow=i; } if (i==iniString.length()-1){ zip.append(val); zip.append(i-slow+1); } } if(zip.length()<iniString.length()){ return zip.toString(); } return iniString; } }
细节:还是输入控制;另外注意所有情况;
1.6 旋转矩阵
不用额外空间
找好对应关系,列式子
import java.util.*; public class Transform { public int[][] transformImage(int[][] mat, int n) { int center=n/2; for (int i=0;i<center;i++) { //行数 for (int j=i;j<n-1-i;j++) { //取对角线为起始 int tmp=mat[i][j]; //旋转 mat[i][j]=mat[n-1-j][i]; mat[n-1-j][i]=mat[n-1-i][n-1-j]; mat[n-1-i][n-1-j]=mat[j][n-1-i]; mat[j][n-1-i]=tmp; } } return mat; } }
1.7 清楚行列
注意一点就可以,全部确定了再清楚,负责可能发生覆盖
类似1.1的方法,用boolean做标记
import java.util.*; public class Clearer { public int[][] clearZero(int[][] mat, int n) { boolean[] line=new boolean[n]; boolean[] row=new boolean[n]; // int lineIndex=0; // int rowIndex=0; for (int i=0;i<n;i++) { for (int j=0;j<n;j++) { if (mat[i][j]==0) { line[i]=true; row[j]=true; } } } for (int i=0;i<n;i++) { for (int j=0;j<n;j++){ if (line[i]==true) { mat[i][j]=0; } if (row[i]==true) { mat[j][i]=0; } } } return mat; } }
1.8 翻转子串
假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串。请将这个算法编写成一个函数,给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成,要求只能调用一次检查子串的函数。
给定两个字符串s1,s2,请返回bool值代表s2是否由s1旋转而成。字符串中字符为英文字母和空格,区分大小写,字符串长度小于等于1000。
测试样例:
"Hello world","worldhello "
返回:false
"waterbottle","erbottlewat"
返回:true
很巧妙地思路:合并两个,然后看是否包含
import java.util.*; public class ReverseEqual { public boolean checkReverseEqual(String s1, String s2) { if (s1 == null || s2 == null || s1.length() != s2.length()) return false; return (s1+s1).contains(s2); } }
---------------拓展-------------------
17.7 数字发音(废物)
有一个非负整数,请编写一个算法,打印该整数的英文描述。
给定一个int x,请返回一个string,为该整数的英文描述。
测试样例:
1234
返回:"One Thousand,Two Hundred Thirty Four"
就三位三位的取,所以没三位做成一个函数来做;
然后注意各个单词放在String[] 中
17.8 最大连续数列和
题目描述
对于一个有正有负的整数数组,请找出总和最大的连续数列。
给定一个int数组A和数组大小n,请返回最大的连续数列的和。保证n的大小小于等于3000。
测试样例:
[1,2,3,-6,1]
返回:6
我的思路:找每一个正数当作起点,然后求和,得到max就好了!!
import java.util.*; public class MaxSum { public int getMaxSum(int[] A, int n) { if (n<=1) return n; int qidian=0; int max=0; for (int i=0;i<A.length;i++) { if(A[i]>0){ qidian=i; int tmp=A[i]; if (tmp>max){ max=tmp; } //max=tmp; for (int j=qidian+1;j<A.length;j++) { tmp=tmp+A[j]; if (tmp>max){ max=tmp; } } } } return max; } }
书上的逻辑没懂,不过第一句话记住了:这题的难度不小(偷笑中)
11.6 矩阵元素查找
有一个NxM的整数矩阵,矩阵的行和列都是从小到大有序的。请设计一个高效的查找算法,查找矩阵中元素x的位置。
给定一个int有序矩阵mat,同时给定矩阵的大小n和m以及需要查找的元素x,请返回一个二元数组,代表该元素的行号和列号(均从零开始)。保证元素互异。
测试样例:
[[1,2,3],[4,5,6]],2,3,6
返回:[1,2]
思路:实现一种折现查找,然后想到的用while
import java.util.*; public class Finder { public int[] findElement(int[][] mat, int n, int m, int x) { int[] ret=new int[2]; //if (n==1 && m==1) return [0,0]; //int line=0; int lie=0; for (int line=0;line<n;line++){ while (mat[line][lie]<x){ if(lie<m-1){ lie++; }else{ line++; } } if(mat[line][lie]==x){ ret[0]=line; ret[1]=lie; return ret; } lie--; } return ret; } }
当然书上的还要巧妙一些:
while(row <mat.length && col>=0){ if (mat[row][col]==x) { return true; }else if(mat[row][col]>n){ col--; }else{ row++; } } return false;
思路是差不多的,只是个人思路是直观一些,书上这个更加抽象~