前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >牛顿法-LeetCode 319、322、324、331、332、389

牛顿法-LeetCode 319、322、324、331、332、389

作者头像
算法工程师之路
发布2019-12-24 17:33:20
5300
发布2019-12-24 17:33:20
举报
文章被收录于专栏:算法工程师之路

作者:TeddyZhang,公众号:算法工程师之路

牛顿法:

LeetCode # 319 322 324 331 332 389

1

编程题

【LeetCode #319】灯泡开关

初始时有 n 个灯泡关闭。第 1 轮,你打开所有的灯泡。第 2 轮,每两个灯泡你关闭一次。第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。第 i 轮,每 i 个灯泡切换一次开关。对于第 n 轮,你只切换最后一个灯泡的开关。找出 n 轮后有多少个亮着的灯泡。

示例: 输入: 3 输出: 1

解题思路:求平方数,使用牛顿法

代码语言:javascript
复制
class Solution {
public:
    int bulbSwitch(int n) {
        if (n < ) return ;
        long r = n;
        while(r * r > n) {
            r = (r + n/r) / ;
        }
        return (int) r;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/bulb-switcher

【LeetCode #322】零钱兑换

给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。

示例 1: 输入: coins = [1, 2, 5], amount = 11 输出: 3 解释: 11 = 5 + 5 + 1

解题思路:

核心递推式:dp[j] = min(dp[j], dp[j-coins[i]]+1); 表示总金额j所需的硬币数,以及减掉一个coins,即dp[j-coins[i]]所需的硬币数再加1。

代码语言:javascript
复制
class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        int INF = amount + ;
        vector<int> dp(amount+, INF+);
        dp[] = ;
        for(int i = ; i < coins.size(); i++) {
            for(int j = coins[i]; j < amount+; j++){
                dp[j] = min(dp[j], dp[j - coins[i]] + );
            }
        }
        return dp[amount] < INF ? dp[amount] : -1;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/coin-change

【LeetCode #324】摆动排序 II

给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]… 的顺序。

示例 1: 输入: nums = [1, 5, 1, 1, 6, 4] 输出: 一个可能的答案是 [1, 4, 1, 5, 1, 6]

解题思路:

首先对nums进行排序,然后从中间开始分开,进行穿插,注意中间点位置的计算,要考虑size为奇数或者偶数,得到统一的公式,mid = (size+1) / 2 - 1.

代码语言:javascript
复制
class Solution {
public:
    void wiggleSort(vector<int>& nums) {
        int size = nums.size();
        vector<int> tmp(nums);
        int end = size-1, mid = (size+) /  - ;
        sort(tmp.begin(), tmp.end());
        for(int i = ; i < size; i++) {
            nums[i] = (i %  == ) ? tmp[mid--] : tmp[end--];
        }
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/wiggle-sort-ii

【LeetCode #331】验证二叉树的前序序列化

序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #。 示例 1: 输入: "9,3,4,#,#,1,#,#,2,#,6,#,#" 输出: true

解题思路:

这道题目可以通过二叉树的性质来解,对于一棵二叉树,其叶子节点的数量是非叶子节点数量 + 1。因此我们初始化degree = 1,每次遇到叶子结点就减1,遇到其他非叶子节点就加1,判断degree最后是否为零即可。

代码语言:javascript
复制
class Solution {
public:
    bool isValidSerialization(string preorder) {
        int degree = ;
        int n = preorder.length();
        for(int i = ; i < n; i++) {
            if (degree == ) return false;
            if (preorder[i] == ',') continue;
            if (preorder[i] == '#') degree -= ;
            else {
                while(i < n && preorder[i] != ',') i++;
                degree += ;
            }
        }
        return degree == ;
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/verify-preorder-serialization-of-a-binary-tree/

【LeetCode #332】重新安排行程

给定一个机票的字符串二维数组 [from, to],子数组中的两个成员分别表示飞机出发和降落的机场地点,对该行程进行重新规划排序。所有这些机票都属于一个从JFK(肯尼迪国际机场)出发的先生,所以该行程必须从 JFK 出发。

示例 1: 输入: [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] 输出: ["JFK", "MUC", "LHR", "SFO", "SJC"]

解题思路:

使用回溯法,需要注意数据结构使用map,这是由于题中的说明,但行程 ["JFK", "LGA"] 与 ["JFK", "LGB"] 相比就更小,排序更靠前,需要有序性。

代码语言:javascript
复制
class Solution {
public:
    int n = ;
    map<string, map<string, int>> mp;
    vector<string> res, tmp;
    vector<string> findItinerary(vector<vector<string>>& tickets) {
        n = tickets.size();
        for(auto& ticket: tickets) {
            ++mp[ticket[]][ticket[]];
        }
        tmp.emplace_back("JFK");
        dfs();
        return res;
    }
    void dfs() {
        if (res.size() == n + ) return;
        if (tmp.size() == n + ) {
            res = tmp;  return;
        }
        for(auto& tt: mp[tmp.back()]) {
            if (tt.second == ) continue;
            --tt.second;
            tmp.emplace_back(tt.first);
            dfs();
            tmp.pop_back();
            ++tt.second;
        }
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/reconstruct-itinerary

【LeetCode #389】找不同

给定两个字符串 s 和 t,它们只包含小写字母。 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。

示例: 输入: s = "abcd" t = "abcde" 输出: e

解题思路:由于t是s的重排再添加一个字母,然后我们直接求和,然后相减即可!

代码语言:javascript
复制
class Solution {
public:
    char findTheDifference(string s, string t) {
        long sum = ;
        for (auto i: t) sum += i;
        for (auto i: s) sum -=i;
        return static_cast<char>(sum);
    }
};

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-the-difference

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 算法工程师之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档