Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false.
Each letter in the magazine string can only be used once in your ransom note.
Note:
You may assume that both strings contain only lowercase letters.
canConstruct(“a”, “b”) -> false
canConstruct(“aa”, “ab”) -> false
canConstruct(“aa”, “aab”) -> true
题意:
前面的字符串里的字母是否被后面字符串的字母包含(注意不需要位置连续)
思路:
采用leetcode热门解法,计算两字符串里26种字母的个数,前面每种字母应小于等于后面
知识点:
1. i++和++i的区别
**总结:
- i都要+1
- j=i++,先执行j=i,然后i+1,所以j=0;
- j=++i,先执行i+1,然后j=i,所以j=1**
原文:http://hinylover.space/2017/07/30/java-i-self-increament/ 从底层解释,非常详细。
截取如下:
int i = 0;
int j1 = i++; // 正确
int j2 = ++i; // 正确
i++; // 正确
++i; // 正确
i++ = 5; // 编译不通过
++i = 5; // 编译不通过
{
int i = 1;
int j1 = i++;
System.out.println("j1=" + j1); // 输出 j1=1
System.out.println("i=" + i); // 输出 i=2
}
{
int i = 1;
int j2 = ++i;
System.out.println("j2=" + j2); // 输出 j2=2
System.out.println("i=" + i); // 输出 i=2
}
无论是i++和++i指令,对于i变量本身来说是没有任何区别,指令执行的结果都是i变量的值加1。而对于j1和j2来说,这就是区别所在。
实现原理
++i和i++实现源码如下:
public class Test {
public void testIPlus() {
int i = 0;
int j = i++; //i=1,j=0
}
public void testPlusI() {
int i = 0;
int j = ++i; //i=1,j=1
}
}
将上面的源代码编译之后,使用javap命令查看编译生成的代码(忽略次要代码)如下:
public void testIPlus();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=1
0: iconst_0 // 生成整数0
1: istore_1 // 将整数0赋值给1号存储单元(即变量i)
2: iload_1 // 将1号存储单元的值加载到数据栈(此时 i=0,栈顶值为0)
3: iinc 1, 1 // 1号存储单元的值+1(此时 i=1)
6: istore_2 // 将数据栈顶的值(0)取出来赋值给2号存储单元(即变量j,此时i=1,j=0)
7: return // 返回时:i=1,j=0
LineNumberTable:
line 4: 0
line 5: 2
line 6: 7
public void testPlusI();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=1
0: iconst_0 // 生成整数0
1: istore_1 // 将整数0赋值给1号存储单元(即变量i)
2: iinc 1, 1 // 1号存储单元的值+1(此时 i=1)
5: iload_1 // 将1号存储单元的值加载到数据栈(此时 i=1,栈顶值为1)
6: istore_2 // 将数据栈顶的值(1)取出来赋值给2号存储单元(即变量j,此时i=1,j=1)
7: return // 返回时:i=1,j=1
LineNumberTable:
line 9: 0
line 10: 2
line 11: 7
2. String
- String类的
length()
方法有() charAt()
方法是字符串的某的位置上的字符转换成char格式,`str.charAt(i)
3. ASC2码的运用
char格式 - char格式 = ASC2码的差值
例如:
int k = 'A'-'a'
/ /k = 97-65=32;
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
int[] num = new int[26];
for(int i=0;i<magazine.length();i++){
num[magazine.charAt(i)-'a']++;
}
for(int i=0;i<ransomNote.length();i++){
num[ransomNote.charAt(i)-'a']--;
//这里由于没有赋值给一个变量,下面的if条件里直接使用,所以可以用x--;
//如果要赋值变量,就要用 int k = --x;
//不能用int k = x--;
if(num[ransomNote.charAt(i)-'a']<0){
return false;
}
}
return true;
}
}