leetcode题解日练--2016.6.17

来源:互联网 发布:电影制作软件下载 编辑:程序博客网 时间:2024/05/18 10:15

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

今日题目:1、罗马数字转整数;2、找BST的最低祖先;3、统计数字二进制表示中1的个数

13. Roman to Integer Difficulty: Easy

Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
题意:将罗马数字转换成阿拉伯数字
思路:
罗马数字有如下符号:
Ⅰ(1)Ⅴ(5)Ⅹ(10)L(50)C(100)D(500)M(1000)
罗马数字的计数规则:
1.若干相同数字连写表示的数是这些罗马数字的和,如III=3;
2.小数字在大数字前面表示的数是用大数字减去小数字,如IV=4;
3.小数字在大数字后面表示的数是用大数字加上小数字,如VI=6;
刚拿到这道题,感觉没什么思路,因为罗马数字感觉与我们平常用的阿拉伯数字相比最大的区别是没有进制,参考了http://blog.sina.com.cn/s/blog_7025794a0101397g.html的思路,自己从1数到100,发现了一些规律
I,1
II,2
III,3
IV,4
V,5
VI,6
VII,7
VIII,8
IX,9

X,10
XI,11
XII,12
XIII,13
XIV,14
XV,15
XVI,16
XVII,17
XVIII,18
XIX,19
XX,20
XXI,21
XXII,22
XXIX,29
XXX,30
XXXIV,34
XXXV,35
XXXIX,39
XL,40
L,50
LI,51
LV,55
LX,60
LXV,65
LXXX,80
XC,90
XCIII,93
XCV,95
XCVIII,98
XCIX,99

C,100
规律就是,从前往后遍历罗马数字,如果某个数比前一个数小,则把该数加入到结果中;反之,则在结果中两次减去前一个数并加上当前这个数;
代码:

class Solution {public:    int romanToInt(string s) {        int result = 0;        string roman = "IVXLCDM";        int count[] = {1,5,10,50,100,500,1000};        result +=count[roman.find(s[0])];        for(int i=1;i<s.length();i++)        {            result+=count[roman.find(s[i])];            int order_prev = roman.find(s[i-1]);            int order = roman.find(s[i]);            if (order>order_prev)                result-=(2*count[roman.find(s[i-1])]);        }        return result;    }};结果:40ms,Your runtime beats 72.99% of cppsubmissions.

第二次刷本题代码

class Solution {public:    int romanToInt(string s) {        int n = s.size();        int count[] = {1,5,10,50,100,500,1000};        string roman = "IVXLCDM";        int res = 0;        for(int i=0;i<n;i++)        {            int num = count[roman.find(s[i])];            res+=num;            if(i+1<n&&roman.find(s[i])<roman.find(s[i+1]))  res-=2*num;        }        return res;    }};

235.Lowest Common Ancestor of a Binary Search Tree Difficulty: Easy

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
题意:给定一棵二叉查找树,找到两个给定节点的最低公共祖先。
__6_
/ \
_2 _8 2和8的最低公共祖先是6,2和4的最低公共祖先是2
/ \ / \
0 _4 7 9
/ \
3 5
思路:这题在《剑指offer》中第50题出现了,因为是二叉查找树,难度降低了很多。我们只需从根节点开始,遍历这棵树,当查询的两个节点不同为某个根节点的子节点的某一侧,即不同位左节点或者不同为右节点的时候,就认为该节点是查询的两个节点的最低公共祖先。
代码:
递归版本

/** * 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:    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {        TreeNode* pNode = root;        if (pNode->left==NULL&&pNode->right==NULL)            return NULL;        if(!((p->val>pNode->val&&q->val>pNode->val)||(p->val<pNode->val&&q->val<pNode->val)))            return pNode;        else if(p->val>pNode->val&&q->val>pNode->val)                return lowestCommonAncestor(pNode->right,p,q);        else             return lowestCommonAncestor(pNode->left,p,q);            }};结果:44ms,Your runtime beats 14.12% of cppsubmissions

迭代版本

class Solution {public:    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {        TreeNode* pNode = root;        while(pNode)        {            if(p->val>pNode->val&&q->val>pNode->val)                pNode = pNode->right;            else if(p->val<pNode->val&&q->val<pNode->val)                pNode = pNode->left;            else                return pNode;        }        return NULL;    }};结果:44ms,Your runtime beats 14.12% of cppsubmissions是否有更快的解法暂时没进行深究。

191.Number of 1 Bits Difficulty: Easy

Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight).
For example, the 32-bit integer ’11’ has binary representation 00000000000000000000000000001011, so the function should return 3.
题意:很简单,就是求32位整型数字的二进制表示中1的个数
思路:这是一道位运算的巧妙运用
1、容易想到的思路,每次将n和1进行亦或运算,会发现除了最低位之外的其他位置保持不变,最低位取反,如果原来最低位是1那么取反后一定比原来的数要小,满足条件就计数一次,然后将n右移一位,程序中需要注意不要越界,时间复杂度O(N);
2、只要数字不为0,每次进行 n&(n-1)的操作,如(5&4就是101&100=100),我们发现1的个数已经减少了1,进行一次计数之后更新n的值进行下一次循环,这样复杂度降到了O(K)。
代码:
1、

class Solution {public:    int hammingWeight(uint32_t n) {        int result=0;        while(n!=0)        {            int tmp = n^1;            if(tmp<n)                result++;            n = n>>1;        }        return result;    }};结果:4ms  Your runtime beats 55.73% of cppsubmissions.

2、

class Solution {public:    int hammingWeight(uint32_t n) {        int result=0;        while(n!=0)        {            n = n&(n-1);            result++;        }        return result;    }};结果:8ms  Your runtime beats 4.95% of cppsubmissions我个人觉得方法二会比方法比方法一快,但是不知道为什么最后确反而慢了,明天再思考一下
0 0
原创粉丝点击