Leetcode算法题

将标题首字母大写

我们顺序遍历title字符串,对于其中每个以空格为分界的单词,找出它的起始与末尾下标,判断它的长度。

class Solution{
public:
	string capitalizeTitle(string title){
		int n = title.size();
		int l = 0, r = 0;
		title.push_back(' ');
		while(r < n){
			while(title[r] != ' '){
				r++;
			}
			if(r - l > 2){
				title[l] = touuper(title[l]);
				l++;
			}
			while(l < r){
				title[l] = tolower(title[l]);
				l++;
			}
			l = r + 1;
			++r;
		}
		title.pop_back();
		return title;
	}
}

快乐数

class Solution {
public:
    int sum(int n){
        int ret = 0;
        while(n){
            ret += ((n%10)*(n%10));
            n/=10;
        }
        return ret;
    }
    bool isHappy(int n) {
        int i = 0;
        while(n != 1){
            i++;
            n = sum(n);
            if(i == 32){
                return false;
            }
        }
        return true;
    }
};

用哈希集合检测循环

在这里插入图片描述
在这里插入图片描述
根据探索,猜测会有三种可能:

  1. 最终得到1
  2. 最终会进入循环
  3. 值会越来越大,最后接近无穷大

在这里插入图片描述

对于 333 位数的数字,它不可能大于 243243243。这意味着它要么被困在 243243243 以下的循环内,要么跌到 111。444 位或 444 位以上的数字在每一步都会丢失一位,直到降到 333 位为止。所以我们知道,最坏的情况下,算法可能会在 243243243 以下的所有数字上循环,然后回到它已经到过的一个循环或者回到 111。但它不会无限期地进行下去,所以我们排除第三种选择。

即使在代码中你不需要处理第三种情况,你仍然需要理解为什么它永远不会发生,这样你就可以证明为什么你不处理它。

完全二叉树的节点个数

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int countNodes(TreeNode* root) {
        if(root == nullptr){
            return 0;
        }else if(root->left == nullptr && root->right == nullptr){
            return 1;
        }
        return 1+countNodes(root->left)+countNodes(root->right);
    }
};

完全二叉树的定义如下:在完全二叉树除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

在受污染的二叉树中查找元素

在这里插入图片描述
在这里插入图片描述

深度优先搜索+哈希表

对二叉树的根节点root进行深度优先搜索,在搜索过程中,根据规则对遍历的节点的值进行恢复,并且将遍历的节点的值加入哈希表valSet中。调用find函数时,返回target值是否存在哈希表valSet中.

class FindElements {
private:
    unordered_set<int> valSet;

    void dfs(TreeNode *node, int val) {
        if (node == nullptr) {
            return;
        }
        node->val = val;
        valSet.insert(val);
        dfs(node->left, val * 2 + 1);
        dfs(node->right, val * 2 + 2);
    }

public:
    FindElements(TreeNode* root) {
        dfs(root, 0);
    }

    bool find(int target) {
        return valSet.count(target) > 0;
    }
};

翻转二叉树

在这里插入图片描述

递归

从根节点开始,递归地对树进行遍历,并从叶子节点开始翻转。
如果当前遍历到的节点root的左右子树都已经翻转,那么只需要交换两棵子树的位置,即可完成以root为根节点的整棵子树的翻转。

class Solution{
public:
	TreeNode* invertTree(TreeNode* root){
		if(root == nullptr){
			return nullptr;
		}
		TreeNode* left = invertTree(root->left);
		TreeNode* right = invertTree(root->right);
		root->left = right;
		root->right = left;
	}
}

汇总区间

给定一个无重复元素的有序整数数组nums。
返回恰好覆盖数组中所有数字的最小有序区间范围列表。
nums的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于nums的数字x。

一次遍历

class Solution {
public:
    vector<string> summaryRanges(vector<int>& nums) {
        vector<string> ret;
        int n = nums.size();
        if(n == 0){
            return ret;
        }
        int begin = 0;
        int end = 0;
        string str = to_string(nums[0]);
        for(int i=1; i<n; i++){
            if(nums[i] == nums[end]+1){
                end++;
            }else{
                if(end!=begin){
                    str.append("->");
                    str.append(to_string(nums[end]));
                }
                begin = ++end;
                ret.push_back(str);
                str = to_string(nums[begin]);
            }
            if(end == n-1){
                if(end!=begin){
                    str.append("->");
                    str.append(to_string(nums[end]));
                }
            }
        }
        ret.push_back(str);
        return ret;
    }
};

2的幂

class Solution {
public:
    bool isPowerOfTwo(int n) {
        int sum = 0;
        while(n>0){
            if(n%2){
                sum++;
            }
            n = n/2;
            if(sum > 1){
                return false;
            }
        }
        if(sum == 1){
            return true;
        }
        return false;
    }
};

有效的字母异位词

t是s的异位词等价于两个字符串排序后相等。

class Solution{
public:
	bool isAnagram(string s,string t){
		if(s.length() != t.length()){
			return false;
		}
		sort(s.begin(), s.end());
		sort(t.begin(), t.end());
		return s==t;
	}
}

最大二进制奇数

题目给定二进制字符串 sss 构造字典序最大的二进制奇数,根据定义可以知道字符串中每一位要么为 000,要么为 111。由于构造的数必须为奇数,则最低位必须为 111,因此我们从字符串 sss 中选择一个 111 放置到最低位。按照贪心原则,其余的 111 全部放在最高位,剩余的 000 放在剩下的位即可,直接构造目标字符串返回即可。

class Solution{
public:
	string maximumOddBinaryNumber(string s){
		int cnt = count(s.begin(),s.end(),'1');
		return string(cnt-1,'1') + string(s.length()-cnt,'0') + '1';
	}
}

Nim游戏

在这里插入图片描述
让我们考虑一些小例子。显而易见的是,如果石头堆中只有一块、两块、或是三块石头,那么在你的回合,你就可以把全部石子拿走,从而在游戏中取胜;如果堆中恰好有四块石头,你就会失败。因为在这种情况下不管你取走多少石头,总会为你的对手留下几块,他可以将剩余的石头全部取完,从而他可以在游戏中打败你。因此,要想获胜,在你的回合中,必须避免石头堆中的石子数为 4 的情况。

  • 如果有5、6、7块石头,只有控制自己拿取的石头数,使对手恰好留下4块,就会输掉比赛。
  • 如果有八块石头,还是会输掉比赛,因为无论挑出1、2、3,对手可以挑3、2、1,使得下一轮时我又有四块。
  • 如果总的石头数不是4的倍数,只要每次取x%4个石头,剩余石头数必然为4的倍数,从而对手会输掉比赛。
  • 15
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

饼干饼干圆又圆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值