35.贪心算法2

发布于:2024-09-19 ⋅ 阅读:(15) ⋅ 点赞:(0)

1.按身高排序(easy)

2418. 按身高排序 - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public String[] sortPeople(String[] names, int[] heights) {
        // 1. 创建⼀个下标数组
        int n = names.length;
        Integer[] index = new Integer[n];
        for (int i = 0; i < n; i++)
            index[i] = i;
        // 2. 对下标数组排序
        Arrays.sort(index, (i, j) -> {
            return heights[j] - heights[i];
        });
        // 3. 提取结果
        String[] ret = new String[n];
        for (int i = 0; i < n; i++) {
            ret[i] = names[index[i]];
        }
        return ret;
    }
}

2.优势洗牌(田忌赛马)

870. 优势洗牌 - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public int[] advantageCount(int[] nums1, int[] nums2) {
        int n = nums1.length;
        // 1. 排序
        Arrays.sort(nums1);
        Integer[] index2 = new Integer[n];
        for (int i = 0; i < n; i++)
            index2[i] = i;
        Arrays.sort(index2, (i, j) -> {
            return nums2[i] - nums2[j];
        });
        // 2. ⽥忌赛⻢
        int[] ret = new int[n];
        int left = 0, right = n - 1;
        for (int x : nums1) {
            if (x > nums2[index2[left]]) {
                ret[index2[left++]] = x;
            } else {
                ret[index2[right--]] = x;
            }
        }
        return ret;
    }
}

3.最长回文串(easy)

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public int longestPalindrome(String s) {
        // 1. 计数 - ⽤数组模拟哈希表
        int[] hash = new int[127];
        for (int i = 0; i < s.length(); i++) {
            hash[s.charAt(i)]++;
        }
        // 2. 统计结果
        int ret = 0;
        for (int x : hash) {
            ret += x / 2 * 2;
        }
        return ret < s.length() ? ret + 1 : ret;
    }
}

4.增减字符串匹配(easy)

942. 增减字符串匹配 - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public int[] diStringMatch(String s) {
        int n = s.length();
        int left = 0, right = n; // ⽤ left,right 标记最⼩值和最⼤值
        int[] ret = new int[n + 1];
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == 'I') {
                ret[i] = left++;
            } else {
                ret[i] = right--;
            }
        }
        ret[n] = left; // 把最后⼀个数放进去
        return ret;
    }
}

5.分发饼干(easy)

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        // 排序
        Arrays.sort(g);
        Arrays.sort(s);
        // 利⽤双指针找答案
        int ret = 0, m = g.length, n = s.length;
        for (int i = 0, j = 0; i < m && j < n; i++, j++) {
            while (j < n && s[j] < g[i])
                j++; // 找饼⼲
            if (j < n)
                ret++;
        }
        return ret;

    }
}

6.最优除法(medium)

553. 最优除法 - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public String optimalDivision(int[] nums) {
        int n = nums.length;
        StringBuffer ret = new StringBuffer();
        // 先处理两个边界情况
        if (n == 1) {
            return ret.append(nums[0]).toString();
        }
        if (n == 2) {
            return ret.append(nums[0]).append("/").append(nums[1]).toString();
        }
        ret.append(nums[0]).append("/(").append(nums[1]);
        for (int i = 2; i < n; i++) {
            ret.append("/").append(nums[i]);
        }
        ret.append(")");
        return ret.toString();
    }
}

7.跳跃游戏 Ⅱ(medium)

45. 跳跃游戏 II - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public int jump(int[] nums) {
        int left = 0, right = 0, ret = 0, maxPos = 0, n = nums.length;
        while (left <= right) // 以防跳不到 n - 1 的位置
        {
            if (maxPos >= n - 1) // 判断是否已经能跳到最后⼀个位置
            {
                return ret;
            }
            for (int i = left; i <= right; i++) {
                // 更新下⼀层的最右端点
                maxPos = Math.max(maxPos, nums[i] + i);
            }
            left = right + 1;
            right = maxPos;
            ret++;
        }
        return -1;
    }
}

8.跳跃游戏(medium)

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public boolean canJump(int[] nums) {
        int left = 0, right = 0, maxPos = 0, n = nums.length;
        while (left <= right) {
            if (maxPos >= n - 1) {
                return true;
            }
            for (int i = left; i <= right; i++) {
                maxPos = Math.max(maxPos, nums[i] + i);
            }
            left = right + 1;
            right = maxPos;
        }
        return false;
    }
}

9.加油站(medium)

. - 力扣(LeetCode)

题目解析

算法原理

 

代码

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n = gas.length;
        for (int i = 0; i < n; i++) // 依次枚举所有的起点
        {
            int rest = 0; // 统计净收益
            int step = 0;
            for (; step < n; step++) // 枚举向后⾛的步数
            {
                int index = (i + step) % n; // ⾛ step 步之后的下标
                rest = rest + gas[index] - cost[index];
                if (rest < 0) {
                    break;
                }
            }
            if (rest >= 0) {
                return i;
            }
            i = i + step; // 优化
        }
        return -1;
    }
}

10.单调递增的数字(medium)

. - 力扣(LeetCode)

题目解析

算法原理

代码

class Solution {
    public int monotoneIncreasingDigits(int n) {
        // 把数字转化成字符串
        char[] s = Integer.toString(n).toCharArray();
        int i = 0, m = s.length;
        // 找第⼀个递减的位置
        while (i + 1 < m && s[i] <= s[i + 1])
            i++;
        if (i == m - 1)
            return n; // 特判⼀下特殊情况
        // 回退
        while (i - 1 >= 0 && s[i] == s[i - 1])
            i--;
        s[i]--;
        for (int j = i + 1; j < m; j++)
            s[j] = '9';
        return Integer.parseInt(new String(s));
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到