leetcode题解日练--2016.7.5

编程日记,尽量保证每天至少3道leetcode题,仅此记录学习的一些题目答案与思路,尽量用多种思路来分析解决问题,不足之处还望指出。标红题为之后还需要再看的题目。

今日题目:1、关灯问题;2、缺失数字;3、先序遍历;4、中序遍历。

319. Bulb Switcher | Difficulty: Medium

There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it’s off or turning off if it’s on). For the ith round, you toggle every i bulb. For the nth round, you only toggle the last bulb. Find how many bulbs are on after n rounds.

Example:

Given n = 3.

At first, the three bulbs are [off, off, off].
After first round, the three bulbs are [on, on, on].
After second round, the three bulbs are [on, off, on].
After third round, the three bulbs are [on, off, off].

So you should return 1, because there is only one bulb is on.
题意:关灯问题,最开始操作1的倍数灯,然后2 的倍数,直到n的倍数。操作就是按一次开关。
思路:
还是从栗子来看,毕竟人蠢:
n取10的时候,i为第i个灯,从1开始计数,如果灯要亮说明需要进行计数次的操作:
i=1 只在第1次操作,共计一次操作
i=2 1/2次操作,共计2次
i=3 1/3次操作,共计2次
i=4 1/2/4次操作,共计3次
i=5 1/5次操作,共计2次
i=6 1/2/3/6次操作,共计4次
i=7 1/7次操作,共计2次
i=8 1/2/4/8.共计4
i=9 1/3/9,共计3次
i=10 1/2/5/10次。共计4次。
将所有奇数次操作的数取出来,1、4、9是仍然亮着的,好像都是平方数。为了验证一下
i=16 1/2/4/8/16 共计5次操作
i=25 1/5/25.共计3次操作
i=36 1/2/4/6/9/18/36 共计7次操作。
这是为什么呢?一个整数在做因式分解的时候,总能表示成另外两个数的乘积,比如24=1*24=2*12=3*8=4*6
这种乘积是两两一组的,但是只有一种情况下会例外,就是完全平方数,比如36=1*3=2*18=3*12=4*9=6*6
也是两两一组,但是中间有一组是6*6,其实这里只做了一次操作,正是这次操作使得灯亮。因此,n个灯的n次操作亮着的灯是

class Solution {
public:
    int bulbSwitch(int n) {
        return sqrt(n);
    }
};

结果:0ms

268. Missing Number | Difficulty: Medium

Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.

For example,
Given nums = [0, 1, 3] return 2.

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
题意:从一个数组中找出确实值
思路:
1、首先根据高斯定理我们能够求出0-n如果不缺应该是多少,然后遍历数组一次我们能算出缺失之后的值,两者之差就是缺失值。
C++

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        int corNum = n*(n+1)/2;
        int wrongNum = 0;
        for(int num : nums)
            wrongNum+=num;
        return corNum-wrongNum;
    }
};

结果:36ms

2、首先,我们将每个数分开看待,可以看成是序号和值两部分,例如0-n之间,有n-1个序号和n-1个值。因为缺失,现在序号只剩下0-n-1,值也只有n个。那么,如何找出缺失值呢?首先,所有缺失序号和值做异或操作肯定为0;因为从0到n每个值都有两个。对于现在0-n-1之间的序号和值分别做异或,然后再异或一个最后的序号n,剩下的就是缺失值了。
C++

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        int res = n;
        for(int i=0;i<n;i++)
        {
            res^=nums[i];
            res^=i;
        }
        return res;
    }
};

结果:36ms

3、首先排序再逐个之间去判断相邻元素是否符合条件

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        for(int i=0;i<n-1;i++)
            if(nums[i+1]-nums[i]>1) return nums[i]+1;
        return nums[0]==0?nums[n-1]+1:0;
    }
};

结果:72ms
4、首先排序好,然后从前往后找到第一个序号与值不想等的元素。
如何查找呢?用二分!!

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        int left=0,right=n;
        int mid=left+(right-left)/2;
        while(left<right)
        {
            mid=left+(right-left)/2;
            if(nums[mid]>mid)   right=mid;
            else    left=mid+1;
        }
        return left;
    }
};

结果:68ms
后两种方法需要是有序的数组,所以时间开销比较大,尽量使用前两种思路。

144. Binary Tree Preorder Traversal QuestionEditorial Solution My Submissions

Total Accepted: 128746
Total Submissions: 316344
Difficulty: Medium
Given a binary tree, return the preorder traversal of its nodes’ values.

For example:
Given binary tree {1,#,2,3},
1
\
2
/
3
return [1,2,3].

Note: Recursive solution is trivial, could you do it iteratively?
题意:后序遍历一棵二叉树。
思路:
递归版本
代码:
C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int>res;
        preTraversal(root, res);
        return res;
    }
    void preTraversal(TreeNode *root, vector<int>&res)
    {
        if(!root)   return;
        res.push_back(root->val);
        preTraversal(root->left,res);
        preTraversal(root->right,res);

    }
};

结果:0ms
2、迭代版本

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int>res;
        stack<TreeNode*> nodes;
        TreeNode *node;
        if(!root) return res;
        nodes.push(root);
        while(!nodes.empty())
        {
            node=nodes.top();
            nodes.pop();
            res.push_back(node->val);
            if(node->right) nodes.push(node->right);
            if(node->left)  nodes.push(node->left);
        }
        return res;
    }
};

结果:0ms

94. Binary Tree Inorder | Difficulty: Medium

Given a binary tree, return the inorder traversal of its nodes’ values.

For example:
Given binary tree [1,null,2,3],
1
\
2
/
3
return [1,3,2].

Note: Recursive solution is trivial, could you do it iteratively?
题意:树的中序遍历。
思路:
1、与后序遍历非常类此,递归就是改一下顺序
递归版

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        inTraversal(root,res);
        return res;
    }
    void inTraversal(TreeNode*root,vector<int>& res)
    {
        if(!root)   return;
        inTraversal(root->left,res);
        res.push_back(root->val);
        inTraversal(root->right,res);
    }
};

结果:0ms
2、迭代版

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        stack<TreeNode*>nodes;
        TreeNode* cur=root;
        if(!root)   return res;
        while(!nodes.empty()||cur)
        {
            while(cur)
            {
            nodes.push(cur);
            cur = cur->left;
            }
            cur=nodes.top();
            res.push_back(cur->val);
            nodes.pop();
            cur = cur->right;
        }


        return res;
    }

};

结果:0ms

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值