leetcode 周赛100(896-899) c++

参考:酒井算协的解答

非常感谢这个公号每周的解答,对于小白的我需要看一会才能明白,于是把自己的一些理解记下来。

896 单调数组

题目:

如果数组是单调递增或单调递减的,那么它是单调的

如果对于所有 i <= jA[i] <= A[j],那么数组 A 是单调递增的。 如果对于所有 i <= jA[i]> = A[j],那么数组 A 是单调递减的。

当给定的数组 A 是单调数组时返回 true,否则返回 false

class Solution {
public:
    bool isMonotonic(vector<int>& A) {
        int l=A.size();
        bool a=true,b=true;
        for(int i=0;i<l-1;i++){
            a=a && (A[i]<=A[i+1]);
            b=b && (A[i]>=A[i+1]);
        }
        return a||b;
    }
};

897递增顺序查找树

题目:

给定一个树,按顺序重新排列树,使树中最左边的结点现在是树的根,并且每个结点没有左子结点,只有一个右子结点。

思路:

其实就是中序遍历。用递归实现。

对于一个节点,递归的找到左子树的递增树,再添加节点本身,再添加其右子树的递增树。

class Solution {
public:
	TreeNode * increasingBST(TreeNode* root) {
		if (!root) return NULL;
		TreeNode* right = increasingBST(root->right);
		TreeNode* ans;
		if (root->left) {
			ans = increasingBST(root->left);	//递归找到root左子树构成的递增顺序查找树
			TreeNode* tmp = ans;
			while (tmp->right) tmp = tmp->right;	//找到这棵树的最右节点
			tmp->right = new TreeNode(root->val);	//把原来的root接上
			tmp->right->right = right;		//再接上root右子树构成的递增顺序查找树。
		}
		else {
			ans = new TreeNode(root->val);
			ans->right = right;
		}
		return ans;
	}
};

898 子数组按位或操作

题目:

我们有一个非负整数数组 A

对于每个(连续的)子数组 B = [A[i], A[i+1], ..., A[j]] ( i <= j),我们对 B 中的每个元素进行按位或操作,获得结果 A[i] | A[i+1] | ... | A[j]

返回可能结果的数量。 (多次出现的结果在最终答案中仅计算一次。)

思路:

重复答案算一次,考虑使用set。
任意连续子序列比较难处理。其实,遍历一遍A,每次让A[i] 和“前面的”、“可以与A[i]构成子序列的”,按位或结果进行按位或。
如何保证“可以与A[i]构成子序列的”,只要让每个A[i]按位或的结果中有A[i-1]就可以了。

具体的看程序中last集合:
{0}
{0, A[0]}
{0, A[0]|A[1], A[1]}
{0, A[0]|A[1]|A[2], A[1]|A[2], A[2] }
...

class Solution {
public:
    int subarrayBitwiseORs(vector<int>& A) {
        set<int> ans;
        set<int> last={0};
        set<int> tmp;
        for(auto a:A){
            tmp.clear();
            for(auto la:last){
                tmp.insert(a|la);
                ans.insert(a|la);
            }
            last=tmp;
            last.insert(0);
        }
        return ans.size();
    }
};

899 有序队列

题目:

给出了一个由小写字母组成的字符串 S。然后,我们可以进行任意次数的移动

在每次移动中,我们选择前 K 个字母中的一个(从左侧开始),将其从原位置移除,并放置在字符串的末尾。

返回我们在任意次数的移动之后可以拥有的按字典顺序排列的最小字符串。

思路:

好吧,又是一道考智商的题。
参考https://leetcode.com/problems/orderly-queue/discuss/165862/Kgreater1-is-bubblesort
上面的解释很好。

如果k>1,我们可以利用把前k个数按我们需要的顺序放到队尾,相当于可以交换任意两个数的位置。
这就和冒泡排序一样了!

所以返回字典序就好。

如果k=1,就相当于所有数排成一圈,找一个起点,字典序最小。
用到了string的substr(i,len),从i开始len长的子串。

class Solution {
public:
    string orderlyQueue(string S, int K) {
        if(K>1){
            sort(S.begin(),S.end()); //返回字典序
            return S;
        }
        else{
            string minS=S;
            for(int i=0,l=S.length();i<l-1;i++){
                S=S.substr(1)+S.substr(0,1); //每次把首位放到末尾
                minS=min(S,minS);
            }
            return minS;
        }
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值