算法刷题笔记一

202 阅读3分钟

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;
    }