512.Decode Ways:点击打开链接
思路:总是从f[i]看前i-1位数字能够解析的结果
有两种方式:前i-1位到前i位,只要第i-1位不是数字0,前i位的结果数就是前i-1位的结果数
前i-2位到前i位,只要第i-2位和第i-1位两位上的数字介于10和26之间,就会又增加一种结果数
注意:1. 新建数组的时候数组长度要多一位,s.length()+1
2. f[0]和f[1]的初始化问题,使得如果第一位为0的字符串,返回的结果数是0
例如:01:f[0]=1, f[1]=0 -> 结果f[2]=f[1]=0
public class Solution {
/**
* @param s a string, encoded message
* @return an integer, the number of ways decoding
*/
public int numDecodings(String s) {
if(s==null || s.length()==0){
return 0;
}
int[] f=new int[s.length()+1];
f[0]=1;
f[1]=s.charAt(0)!='0'?1:0;
for(int i=2;i<=s.length();i++){
if(s.charAt(i-1)!='0'){
f[i]=f[i-1];
}
int twoDigits=(s.charAt(i-2)-'0')*10+s.charAt(i-1)-'0';
if(twoDigits>=10 && twoDigits<=26){
f[i]+=f[i-2];
}
}
return f[s.length()];
}
}
638.Strings Homomorphism:点击打开链接
思路:两次映射,s->t一次,t->s一次
注意:不能只做一次映射,如果"app"->"dog"是可以的,但是"dog"->"app"就犯了两个字母映射到同一个字母的错误
public class Solution {
/**
* @param s a string
* @param t a string
* @return true if the characters in s can be replaced to get t or false
*/
public boolean isIsomorphic(String s, String t) {
if(s==null || t==null){
return true;
}
Map<Character,Character> map=new HashMap<>();
for(int i=0;i<s.length();i++){
if(!map.containsKey(s.charAt(i))){
map.put(s.charAt(i),t.charAt(i));
}else{
if(map.get(s.charAt(i))!=t.charAt(i)){
return false;
}
}
}
Map<Character,Character> mapSecond=new HashMap<>();
for(int i=0;i<t.length();i++){
if(!mapSecond.containsKey(t.charAt(i))){
mapSecond.put(t.charAt(i),s.charAt(i));
}else{
if(mapSecond.get(t.charAt(i))!=s.charAt(i)){
return false;
}
}
}
return true;
}
}
public class Solution {
/**
* @param s a string
* @param t a string
* @return true if the characters in s can be replaced to get t or false
*/
public boolean isIsomorphic(String s, String t) { //写法二:同样的思路
if(s==null || t==null){
return true;
}
HashMap<Character,Character> map = new HashMap<>();
HashSet<Character> repeat = new HashSet<>();
for(int i = 0;i<s.length();i++){ //例如"dog"->"app"
if(!map.containsKey(s.charAt(i))){ //遍历到第三个字母,map不包含字母g,但是repeat已经有p
if(repeat.contains(t.charAt(i))){ //repeat的p是遍历第二个字母的时候放进去的
return false;
}
map.put(s.charAt(i) , t.charAt(i)); //在双方都没有的情况下,map和repeat同步加入
repeat.add(t.charAt(i));
}else{
if(map.get(s.charAt(i)) != t.charAt(i)){
return false;
}
}
}
return true;
}
}
626.Rectangle Overlap:点击打开链接
思路:考虑不重合的情况,有四种相对位置
/**
* Definition for a point.
* class Point {
* public int x, y;
* public Point() { x = 0; y = 0; }
* public Point(int a, int b) { x = a; y = b; }
* }
*/
public class Solution {
/**
* @param l1 top-left coordinate of first rectangle
* @param r1 bottom-right coordinate of first rectangle
* @param l2 top-left coordinate of second rectangle
* @param r2 bottom-right coordinate of second rectangle
* @return true if they are overlap or false
*/
public boolean doOverlap(Point l1, Point r1, Point l2, Point r2) {
if(l1.x>r2.x || r1.x<l2.x){
return false;
}
if(l1.y<r2.y || r1.y >l2.y){
return false;
}
return true;
}
}
637.Check Word Abbreviation:
点击打开链接
思路:两个指针,分别指向两个字符串的起始位置,往后遍历,出现的情况只有数字和字母,做相应处理,直到最后
public class Solution {
/**
* @param word a non-empty string
* @param abbr an abbreviation
* @return true if string matches with the given abbr or false
*/
public boolean validWordAbbreviation(String word, String abbr) {
if(word==null || abbr==null){
return false;
}
int i=0;int j=0;
char[] w=word.toCharArray(); //方便后面用a[j]的形式,不用charAt麻烦
char[] a=abbr.toCharArray();
while(i<word.length() && j<abbr.length()){ //出现的只有数字和字母两种情况
if(a[j]>='0' && a[j]<='9'){ //如果是数字,不能有前导零
if(a[j]=='0'){
return false;
}
int val=0;
while(j<abbr.length() && a[j]>='0' && a[j]<='9'){ //非前导零的情况拿出连着的数字的大小
val=val*10+a[j++]-'0';
}
i+=val; //同时指向字符串word的指针移动相应的位数
}else{ //如果是字母,要看两边相对应的是否相同
if(w[i++]!=a[j++]){
return false;
}
}
}
return i==word.length() && j==abbr.length(); //直到判断到头,因为i++和j++正好是最后一个字符
} //所有i和j多一个,要到字符串的长度
}
639. Words Abbreviation:点击打开链接
思路:每一个单词装在HashMap里并计数,有重复就增加此单词的prefix[i]继续求,直到所有的都为unique
注意:最后HashMap里装的是分析过的所有情况的个数,而result数组里的才是结果
例如:"apple", “apble”
最后map里{apple=1,a3e=2,apble=1,ap2e=2}
最后result数组里{apple,apble}
public class Solution {
/**
* @param dict an array of n distinct non-empty strings
* @return an array of minimal possible abbreviations for every word
*/
public String[] wordsAbbreviation(String[] dict) {
if(dict==null || dict.length==0){
return new String[0];
}
int len = dict.length;
String[] result = new String[len];
int[] prefix = new int[len];
Map<String, Integer> map = new HashMap<>();
boolean unique = true;
for(int i = 0; i < dict.length;i++){
prefix[i] = 1;
result[i] = getAbbre(dict[i], prefix[i]);
if(!map.containsKey(result[i])){
map.put(result[i], 1);
}else{
map.put(result[i], map.get(result[i]) + 1);
unique = false;
}
}
while(unique==false){
unique=true;
for(int i = 0; i < len; i ++){
if(map.get(result[i]) > 1){
prefix[i]++; //个数大于1里面的每一个的substring都要多一位
result[i] = getAbbre(dict[i], prefix[i]);
if(!map.containsKey(result[i])){
map.put(result[i], 1);
}else{
map.put(result[i], map.get(result[i]) + 1);
unique=false;
}
}
}
if(unique==true){ //直到每一个unique=true
break;
}
}
return result;
}
private String getAbbre(String s,int prefix){
if(s.length()-prefix<=2){
return s;
}
return s.substring(0,prefix)+(s.length()-prefix-1)+s.charAt(s.length()-1); //substring方法参数(起始位置,长度)
}
}