• 数字问题-LeetCode 462、463、473、474、475、476、477、482(二分)


    LeetCode # 462 463 473 474 475 476 477 482

    1
    编程题
    【LeetCode #462】最少移动次数使数组元素相等

    给定一个非空整数数组,找到使所有数组元素相等所需的最小移动数,其中每次移动可将选定的一个元素加1或减1。 您可以假设数组的长度最多为10000。

    例如:
    输入:
    [1,2,3]
    输出:
    2

    解题思路:这个题目的关键是找出中位数,然后每个数字的移动目标都是这个中位数即可!
    注意,当数组长度为偶数时,中位数是中间两个数的平均值,因此我们需要分别去验证。

    class Solution {
    public:
    int minMoves2(vector& nums) {
    if (nums.size() == 0) return 0;
    sort(nums.begin(), nums.end());
    int n = nums.size();
    if (n & 1 == 1) return Solve(nums[n/2], nums); // n为奇数,中位数为中间的数
    else return min(Solve(nums[n/2], nums), Solve(nums[n/2-1], nums));
    }
    private:
    int Solve(int target, vector& nums) {
    int res = 0;
    for(auto num: nums) {
    res += abs(target - num);
    }
    return res;
    }
    };
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii

    【LeetCode #463】岛屿的周长

    给定一个包含 0 和 1 的二维网格地图,其中 1 表示陆地 0 表示水域。

    网格中的格子水平和垂直方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。

    岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。

    解题思路:直接进行遍历,对四个边界进行处理后,然后从行和列比较相邻两个数是否相同,如果不同,周长+1.

    class Solution {
    public:
    int islandPerimeter(vector<vector>& grid) {
    int res = 0;
    for(int i = 0; i < grid.size(); i++) {
    for(int j = 0; j < grid[i].size(); j++) {
    if (i == 0 && grid[i][j] == 1) res++;
    if (i == grid.size()-1 && grid[i][j] == 1) res++;
    if (j == 0 && grid[i][j] == 1) res++;
    if (j == grid[i].size()-1 && grid[i][j] == 1) res++;
    if (i != 0) {
    if (grid[i][j] != grid[i-1][j]) res++;
    }
    if (j != 0) {
    if (grid[i][j] != grid[i][j-1]) res++;
    }
    }
    }
    return res;
    }
    };
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/island-perimeter

    【LeetCode #473】火柴拼成正方形

    还记得童话《卖火柴的小女孩》吗?现在,你知道小女孩有多少根火柴,请找出一种能使用所有火柴拼成一个正方形的方法。不能折断火柴,可以把火柴连接起来,并且每根火柴都要用到。

    输入为小女孩拥有火柴的数目,每根火柴用其长度表示。输出即为是否能用所有的火柴拼成正方形。

    示例 1:
    输入: [1,1,2,2,2]
    输出: true

    class Solution {
    private:
    bool dfs(vector& nums, vector& vis, int i, int avg, int sum) {
    vis[i] = true;
    sum += nums[i];
    if (sum == avg) return true;
    for (int j = i-1; j >= 0; j--) {
    if (!vis[j] && nums[j] + sum <= avg) {
    if (dfs(nums, vis, j, avg, sum)) return true;
    vis[j] = false;
    }
    }
    return false;
    }
    public:
    bool makesquare(vector& nums) {
    if (nums.size() < 4) return false;
    sort(nums.begin(), nums.end());
    vector vis(nums.size(), false);
    int avg = 0, i = nums.size()-1;
    for(auto num: nums) avg += num;
    if (avg % 4) return false;
    avg /= 4;
    if (nums.back() > avg) return false; // 最大边大于边长
    for(int j = 0; j < 4; j++) {
    while(vis[i]) i--;
    if (!dfs(nums, vis, i, avg, 0)) return false;
    }
    return true;
    }
    };
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/matchsticks-to-square

    【LeetCode #474】一和零

    在计算机界中,我们总是追求用有限的资源获取最大的收益。
    现在,假设你分别支配着 m 个 0 和 n 个 1。另外,还有一个仅包含 0 和 1 字符串的数组。
    你的任务是使用给定的 m 个 0 和 n 个 1 ,找到能拼出存在于数组中的字符串的最大数量。每个 0 和 1 至多被使用一次。

    注意:
    给定 0 和 1 的数量都不会超过 100。
    给定字符串数组的长度不会超过 600。

    class Solution {
    public:
    int findMaxForm(vector& strs, int m, int n) {
    if (strs.empty() || (m <= 0 && n <= 0)) return 0;
    vector<vector> dp(m+1, vector(n+1, 0));

        for(auto str: strs) {
            int zero_cnt = 0, one_cnt = 0;
            for(auto ch: str) {
                if (ch == '0') zero_cnt ++;
                else one_cnt ++;
            }
            for(int i = m; i >= 0; --i) {
                for(int j = n; j >= 0; --j) {
                    if (i >= zero_cnt && j >= one_cnt)
                        dp[i][j] = max(dp[i][j], dp[i-zero_cnt][j-one_cnt] + 1);
                }
            }
        }
    
    
        return dp[m][n];
    }
    

    };
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/ones-and-zeroes

    【LeetCode #475】供暖器

    冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。

    现在,给出位于一条水平线上的房屋和供暖器的位置,找到可以覆盖所有房屋的最小加热半径。

    所以,你的输入将会是房屋和供暖器的位置。你将输出供暖器的最小加热半径。

    示例 1:
    输入: [1,2,3],[2]
    输出: 1
    解释: 仅在位置2上有一个供暖器。如果我们将加热半径设为1,那么所有房屋就都能得到供暖。

    解题思路:

    首先将house和heater数组进行排序,然后遍历house,每次遍历时,都去找离house最近的heater,然后得到最小距离,存为tmp。
    最后结果就是所有house对应的tmp的最大值!

    class Solution {
    public:
    int findRadius(vector& houses, vector& heaters) {
    sort(houses.begin(), houses.end());
    sort(heaters.begin(), heaters.end());
    int maxLen = 0;
    for(int i = 0; i < houses.size(); i++) {
    int low = 0, high = heaters.size()-1;
    int tmp = INT_MAX;
    while(low <= high) {
    int mid = low + (high-low) / 2;
    if (heaters[mid] == houses[i]) {
    tmp = 0; break;
    }
    else if (heaters[mid] > houses[i]) { // 暖气在房子的右边,应该再往左边找
    tmp = min(tmp, heaters[mid] - houses[i]);
    high = mid - 1;
    }
    else {
    tmp = min(tmp, houses[i] - heaters[mid]);
    low = mid + 1;
    }
    }
    maxLen = max(tmp, maxLen);
    }
    return maxLen;
    }
    };
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/heaters

    【LeetCode #476】数字的补数

    给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。

    解题思路:一个正整数的补数是2 ^ (二进制数的个数) - 1 -num. 比如5的补数是2,也就是2^3-1-5 = 2.

    class Solution {
    public:
    int findComplement(int num) {
    int sz = log(num) / log(2) + 1;
    return pow(2, sz) - 1 - num;
    }
    };
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/number-complement/

    【LeetCode #477】汉明距离总和

    两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。

    计算一个数组中,任意两个数之间汉明距离的总和。

    示例:
    输入: 4, 14, 2
    输出: 6

    解题思路:

    使用一个cnt数组保存nums数组中某 i 位是 1 的个数,比如cnt[3]=2,表示这些数中第3位是1的有两个,那么汉明距离就是2*(n-2),其中n-2就是零的个数。

    class Solution {
    public:
    int totalHammingDistance(vector& nums) {
    vector cnt(32, 0);
    for(auto num: nums) {
    int i = 0;
    while(num) {
    if (num & 1) {
    cnt[i]++;
    }
    num = num >> 1;
    i++;
    }
    }
    int res = 0;
    int n = nums.size();
    for(auto c: cnt) {
    res += c * (n-c);
    }
    return res;
    }
    };
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/total-hamming-distance

    【LeetCode #482】秘钥格式化

    给定一个密钥字符串S,只包含字母,数字以及 '-'(破折号)。N 个 '-' 将字符串分成了 N+1 组。给定一个数字 K,重新格式化字符串,除了第一个分组以外,每个分组要包含 K 个字符,第一个分组至少要包含 1 个字符。两个分组之间用 '-'(破折号)隔开,并且将所有的小写字母转换为大写字母。

    给定非空字符串 S 和数字 K,按照上面描述的规则进行格式化。

    示例 1:
    输入:S = "5F3Z-2e-9-w", K = 4
    输出:"5F3Z-2E9W"

    class Solution {
    public:
    string licenseKeyFormatting(string S, int K) {
    int num = K - (S.size()-count(S.begin(), S.end(), '-') % K); // 如果不能整除K,那么多余的将在第一个分组
    string res = "";
    for(auto ch: S) {
    if (ch == '-') continue;
    if (num == 0 && res != "") res += '-';

            res += toupper(ch);
            num = (num+1) % K;
        }
        return res;
    }
    

    };
    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/license-key-formatting

  • 相关阅读:
    jQuery学习易忘细节
    mysql关键字与自己设置的字段冲突
    jquery导航栏html页面跳转导航字体变色
    css解决谷歌,360浏览器默认最小字体为12px问题
    ThinkPHP中关于JS文件如何添加类似__PUBLIC__图片路径
    (谷歌浏览器等)解决css中点击input输入框时出现外边框方法【outline:medium;】
    为何在font-family属性中设置多个值
    jquery实现简单的Tab切换菜单
    Thinkphp下嵌套UEditor富文本WEB编辑器
    thinkphp框架下404页面设置
  • 原文地址:https://www.cnblogs.com/niaocaizhou/p/12143160.html
Copyright © 2020-2023  润新知