Leetcode 242:
https://leetcode.com/problems/valid-anagram/description/
题目的第一想法:
这道题的我个人的第一想法是使用直接hashtable,对存在的每个string A中的char做一个count。再在B中的string的char做一个count--。最后遍历整个hashtable来查看是不是所有的char的count都为零,如果不是return false,如果是return true。写法如下
class Solution {
public boolean isAnagram(String s, String t) {
HashMap<Character, Integer> map = new HashMap<>();
StringBuilder sb = new StringBuilder(s);
for(int i = 0; i < sb.length(); i++){
if(map.containsKey(sb.charAt(i))){
map.put(sb.charAt(i), map.get(sb.charAt(i)) + 1);
}else{
map.put(sb.charAt(i), 1);
}
}
sb = new StringBuilder(t);
for(int i = 0; i < sb.length(); i++){
if(map.containsKey(sb.charAt(i))){
map.put(sb.charAt(i), map.get(sb.charAt(i)) - 1);
}else{
return false;
}
}
for(int c: map.values()){
if(c != 0){
return false;
}
}
return true;
}
}
更好的解法:
如果直接使用hashtable的话,在时间上很慢。个人的猜测是创建,遍历,更改一个较为复杂的数据结构需要的时间比较多。所以其实在这个问题上,直接使用一个数组来代替是更好的解法。因为数组的查找和更改在时间复杂度上和hashtable一样都是O(1)。写法如下
class Solution {
public:
bool isAnagram(string s, string t) {
int alpha[26] = {0};
for(int i = 0; i < s.size(); i++){
alpha[s[i] - 'a']++ ;
}
for(int i = 0; i < t.size(); i++){
alpha[t[i] - 'a']-- ;
}
for(int i = 0; i <26; i++){
if(alpha[i] != 0){
return false;
}
}
return true;
}
};
Leetcode 349:
https://leetcode.com/problems/intersection-of-two-arrays/description/
题目的第一想法:
这道题我的第一想法是使用Hashset来储存第一个数组中的值,然后再用第二个数组中的值来对比hashset中储存的值进而得到intersection。使用hashset有两个天然优势,一是搜索速度较快,二是set不允许有重复值的存在避免了除重的冗余操作。写法如下
class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> set = new HashSet<>();
HashSet<Integer> rset = new HashSet<>();
for(int i = 0; i < nums1.length; i++){
set.add(nums1[i]);
}
for(int i = 0; i < nums2.length; i++){
if(set.contains(nums2[i])){
rset.add(nums2[i]);
}
}
int[] arr = new int[rset.size()];
int i = 0;
for(Integer num: rset){
arr[i] = num;
i++;
}
return arr;
}
}
Leetcode 349:
https://leetcode.com/problems/intersection-of-two-arrays/description/
题目的第一想法:
这道题我没有看懂。对于“Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1.”这句话我不是很理解它的意思。但大概可以理解为如果是1,就停止loop,如果不是就永远继续。但对于停止条件我刚开始依旧没有很好的想法。
看完代码随想录之后的想法:
看完之后我理解了使用Hashset的理由,确实本质上来说这道题依旧是一道查重的问题。个人感觉这种拨开表面看本质的能力还需要做更多的问题来培养。
class Solution {
public boolean isHappy(int n) {
HashSet<Integer> set = new HashSet<>();
int num = numDet(n);
while(num != 1 || !set.contains(num)){
set.add(num);
num = numDet(num);
if(num == 1){
return true;
}else if(set.contains(num)){
return false;
}
}
return false;
}
public int numDet(int n){
int sum = 0;
while(n > 0){
int num = n % 10;
sum += num * num;
n = n / 10;
}
return sum;
}
}
Leetcode 1:
https://leetcode.com/problems/intersection-of-two-arrays/description/
题目的第一想法:
这道题因为以前做过比较多遍了,所以对各个解法都有了解。基本上有两种比较好的解法:一是用hashmap,另一种sort之后使用双指针。用hashmap的话时间复杂度是O(N),空间复杂的是O(N);而使用双指针的解法的时间复杂度则是O(nlgn)而空间复杂度则是O(N)。
以下是hashmap的思路:检查hash中有没有target-value的数字,如果有的话就返回pair。不然就将当前的value放入hash后继续检查其他数字。需要注意的是我们希望key是数组中存在的value,而index则需要储存在value的位置。写法如下
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] r = new int[2];
HashMap<Integer, Integer> hash = new HashMap<>();
for(int i = 0; i < nums.length; i++){
if(hash.containsKey(target - nums[i])){
r[0] = i;
r[1] = hash.get(target - nums[i]);
return r;
}else{
hash.put(nums[i], i);
}
}
return r;
}
}