Given a roman numeral, convert it to an integer.
Input is guaranteed to be within the range from 1 to 3999.
把一个罗马数字转换成十进制,范围是1到3999
为了编个程,把罗马有数字学了一遍。。。
简单说一下罗马数字的构造规则
首先罗马数字由7个基本数字组成
I=1, V=5, X=10, L=50, C=100, D=500, M=1000,规则如下:
其实在分析了题目之后,就能明白,对规则的判断并不是我们所需要考虑的,因为既然是罗马数字转换,那么它输入的肯定是罗马数字,所以这样以来就简单多了,我们只需要判断怎么计算罗马数字就行了。
那么怎么计算呢,横线不用判断,因为4000以内不用划横线,所以就是加减的事情了,主要判断什么时候加,什么时候减,当当前的数小于后一个数时,那么就应该减去当前的数,除此之外都能该加上该数,即使数字重复,其实也是加,因为重复几次就是几倍,相当于加了几次。
第一种代码如下:
int romanToInt(char* s) {
int length = strlen(s);
int *sn = (int *)malloc(sizeof(int) * length);
for (int i = 0; i < length; i++){
switch (s[i]){
case 'I': sn[i] = 1;
break;
case 'V': sn[i] = 5;
break;
case 'X': sn[i] = 10;
break;
case 'L': sn[i] = 50;
break;
case 'C': sn[i] = 100;
break;
case 'D': sn[i] = 500;
break;
case 'M': sn[i] = 1000;
break;
default:
break;
}
}
int sum = sn[0];
for (int i = 1; i < length; i++){
if (sn[i] > sn[i-1]) sum = sum - 2 * sn[i-1];
sum += sn[i];
}
free(sn);
return sum;
}
第二种
int romanToInt(char* s) {
int length = strlen(s);
int sn[256];
sn['I'] = 1; sn['V'] = 5; sn['X'] = 10; sn['L'] = 50; sn['C'] = 100; sn['D'] = 500; sn['M'] = 1000;
int sum = sn[s[0]];
for (int i = 1; i < length; i++){
if (sn[s[i]] > sn[s[i-1]]) sum = sum - 2 * sn[s[i-1]];
sum += sn[s[i]];
}
return sum;
}
结果显示,这两种代码的耗时没有什么分别,那么switch语句还是效率挺高的。
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common
ancestor is defined between two nodes v and w as the lowest node in T
that has both v and w as descendants (where we allow a node to be a
descendant of itself).”_______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5
For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another example is LCA of nodes 2 and 4 is 2, since a
node can be a descendant of itself according to the LCA definition.
这道题的大意就是给定一个顺序二叉树,给定两个节点,找出两个节点最低的共同父节点。
二叉树,考虑的思路肯定是递归,那么怎么递归?很简单,从根结点进入,开始比较,有三种情况,
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {
if (!root)
return NULL;
if (root->val >= p->val && root->val <= q->val ||
root->val <= p->val && root->val >= q->val)
return root;
if (root->val > p->val && root->val > q->val)
return lowestCommonAncestor(root->left, p, q);
if (root->val < p->val && root->val < q->val)
return lowestCommonAncestor(root->right, p, q);
}
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的个数。
有个比较简单的思路,那就是移位,大部分人也就是用的这个思路,只要n不等于0,就移位,如果当前为奇数就加一
int hammingWeight(uint32_t n) {
int count = 0;
while (n){
if (n % 2 == 1)count ++;
n = n >> 1;
}
return count;
}
还有一种思路,不用判断奇偶,计数的变量count每次加上n&1,这样如果个位是0,就相当于加了0
int hammingWeight(uint32_t n) {
int count = 0;
while (n){
count = count + (n & 1);
n = n >> 1;
}
return count;
}
但是在dicuss里面发现了一个很有技巧的代码,以前没有发现这个规律,
n与n-1相与,会消掉最左边的一个1
所以代码就成了这样:
int count = n ? 1 : 0;
while(n &= (n-1)) count++;
return count;
}
Given a sorted linked list, delete all duplicates such that each element appear
only once.For example, Given 1->1->2, return 1->2. Given 1->1->2->3->3, return
1->2->3.
在排序好的连表中删除重复的节点
思路很简单,从头遍历,如果第一个等于第二个,那么就删除一个。如果不是继续向前走。
两种写法,一种两个指针,一种一个指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteDuplicates(struct ListNode* head) {
if (!head)
return NULL;
struct ListNode *p, *q;
p = head;
q = head->next;
while (q){
if (p->val == q->val){p->next = q->next; q = p->next;}
else {p = q; q = q->next;}
}
return head;
}
一个指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteDuplicates(struct ListNode* head) {
if (!head)
return NULL;
struct ListNode *p;
p = head;
while (p && p->next){
if (p->val == p->next->val){p->next = p->next->next;}
else {p = p->next;}
}
return head;
}
分析:一个指针省空间费时间,两个指针,非空间省时间。