leetCode第242题:有效的字母异位词。
原文链接: leetcode-cn.com/problems/va…
思路一:排序
/*
思路一:将两个字符串中的字符排序之后在比较字符串是否相等
快排时间复杂度O(nlgn),空间复杂度O(1)
*/
public static boolean isAnagram(String s, String t) {
if (s.length() != t.length())
return false;
char[] str1 = s.toCharArray();
char[] str2 = t.toCharArray();
Arrays.sort(str1);
Arrays.sort(str2);
return Arrays.equals(str1, str2);
}
思路二:hash表
/*
用hash表存储每个字符在字符串中出现的次数,比较两者出现的次数是否相同
由于题目限定字符串都为小写字母,因此用长度为26的数组来存储即可
时间复杂度O(n),空间复杂度O(n)
*/
public static boolean isAnagram2(String s, String t) {
if (s.length() != t.length())
return false;
int[] counter = new int[26];
for (int i = 0; i < s.length(); i++) {
counter[s.charAt(i) - 'a']++;
counter[t.charAt(i) - 'a']--;
}
//最后counter数组若有不为0的值,则返回false
for (int count : counter) {
if (count != 0)
return false;
}
return true;
}
思路三:hashmap
/*
题目进阶:若字符允许为unicode字符应该怎么办?
此时用counter数组行不通,数组范围太大。应该用hash表的实现类hashmap来比较字符的次数
时间复杂度O(n),空间复杂度O(n)
*/
public static boolean isAnagram3(String s, String t) {
if (s.length() != t.length())
return false;
Map<Character, Integer> map = new HashMap<>();
for (char c : s.toCharArray()) {
map.put(c, map.getOrDefault(c, 0) + 1);
}
for (char c : t.toCharArray()) {
Integer count = map.get(c);
if (count == null) {
return false;
} else if (count > 1) {
map.put(c, count - 1);
} else {
map.remove(c);
}
}
return map.isEmpty();
}
leetcode53:最大子序列和:
原文链接:leetcode-cn.com/problems/ma…
思路一:正数增益,当前和为正数则对数组中的下一个数为增益效果
public static int maxSubArray(int[] array) {
int res = array[0];
int sum = array[0];
for (int i = 1; i < array.length; i++) {
if (sum > 0)
sum += array[i];
else
sum = array[i];
res = Math.max(res, sum);
}
return res;
}
leetcode169:求众数:
原文链接:leetcode-cn.com/problems/ma…
思路一:用hashmap
/*
思路一:利用hashMap,遇到相同的数次数加1
时间复杂度O(n),空间复杂度O(n)
*/
public int majorityElement(int[] nums) {
if (nums.length == 1)
return nums[0];
Map<Integer, Integer> map = new HashMap<>();
int len = nums.length;
//利用hash表存储
for (int i = 0; i < len; i++) {
if (map.containsKey(nums[i])) {
map.put(nums[i], map.get(nums[i]) + 1);
if (map.get(nums[i]) > len / 2)
return nums[i];
} else {
map.put(nums[i], 1);
}
}
return 0;
}
思路二:排序
/*
思路二:题目说了数组肯定存在众数,所以可以先对数组排序,取nums[nums.length/2]
时间复杂度O(nlgn)
关于排序:可手写排序算法也可用Arrays.sort
关于Arrays.sort再看看篇笔记:https://book.douban.com/annotation/15154366/
*/
public int majorityElement2(int[] nums) {
Arrays.sort(nums);
return nums[nums.length/2];
}
leetCode122:买卖股票的最佳时机
原文链接:leetcode-cn.com/problems/be…
思路:用贪心算法,买入时机:只要第二天价格比第一天价格高就买入然后在第二天售出.
实际中肯定不会这么做,因为股票具有不可预测性。而练手的题目数据可以预测。
/*
贪心算法:时间复杂度O(n)
*/
public int maxProfit(int[] prices) {
int res = 0;
int temp = 0; //记录差值
for (int i = 0; i < prices.length - 1; i++) {
temp = prices[i + 1] - prices[i];
if (temp > 0)
res = res + temp;
}
return res;
}
LeetCode860:卖柠檬水找零
原文链接:leetcode.com/problems/le…
思路:我们只需记录5元和10元面值的的个数即可。
收到5元时:5块的数量加一
收到10块时:10块的数量加一,五块的数量减一
收到20块时:两种情况。用贪心算法我们尽可能多保留五块的数量。优先十块数量减一,五块数量减一。
/*
贪心算法解找零钱问题:时间复杂度O(n)
*/
public boolean lemonadeChange(int[] bills) {
int n = bills.length;
int count5 = 0, count10 = 0;
for (int bill : bills) {//对三种情况进行判断
if (bill == 5) {
count5++;
} else if (bill == 10) {
count10++;
count5--;
} else if (bill == 20) {
if (count10 == 0 && count5 >= 0) {
count5 -= 3;
} else {
count10--;
count5--;
}
}
if (count5 < 0 || count10 < 0)
return false;
}
return count5 >= 0 && count10 >= 0;
}
leetcode455:分发饼干
原文链接:leetcode-cn.com/problems/as…
贪心法,对两个数组排序,用尽量小的饼干满足胃口没那么大的孩子。
public int findContentChildren(int[] g, int[] s) {
//贪心的思想是:用尽量小的饼干去满足小胃口的朋友
int child = 0;
int cookie = 0;
Arrays.sort(g);
Arrays.sort(s);
while(child<g.length && cookie<s.length){
if(g[child]<=s[cookie]){
child++;
}
cookie++;
}
return child;
}