二进制中1的个数
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路
n&(n-1)会每次都减少一个数字1
例如可以通过n&(n-1)判断这个数是不是2的幂次,如果是则这值为01
2
3
4
5
6
7
8
9
10
11
12class Solution {
public:
int NumberOf1(int n) {
int count=0;
while(n!=0)
{
count++;
n=n&(n-1);
}
return count;
}
};
O(1)的时间内删除链表的节点
1 | void DeleteNode(ListNode* head,ListNode* toDeNode) |
调整数组顺序使奇数位于偶数前面
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28class Solution {
public:
int isEven(int x)
{
return (x & 1) == 0;
}
void reOrderArray(vector<int> &array) {
vector<int> odd;
vector<int> even;
int len=array.size();
vector<int>::iterator it;
for(it=array.begin();it!=array.end();it++)
{
if (isEven(*it))
even.push_back(*it);
else
odd.push_back(*it);
}
array.clear();
array.resize(len);
int oddLen=odd.size();
copy(odd.begin(),odd.end(),array.begin());
copy(even.begin(),even.end(),array.begin()+oddLen);
}
};
链表中倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
1 | /* |
判断链表是否有环
用快慢指针1
2
3
4
5
6
7
8
9
10
11
12
13
14
15bool isloop(ListNode*head)
{
if(head==NULL||head->next==NULL)
return false;
ListNode *slow=head;
ListNode *fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return true;
}
return false;
}
那么如何找出入口地址呢?
如图,为了简单起便,我们假设快指针只转了一圈,就与慢指针相遇了。此时,
慢指针走了 AB+BC
快指针走了 AB+BC+CB+BC
则,2(AB+BC)=AB+BC+CB+BC
AB=CB
则可以在相遇的时候,从表头再设置一个指针,等他们相遇的时候,就是入口处1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21ListNode* isloop(ListNode*head)
{
if(head==NULL||head->next==NULL)
return false;
ListNode *slow=head;
ListNode *fast=head;
while(fast!=NULL&&fast->next!=NULL)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
break;
}
ListNode *p=head;
while(p!=slow)
{
p=p->next;
slow=slow->next;
}
return p;
}
判断两个单向链表是否相交
思路
若两个链表相交,则他们从交点开始,后面都是一样的。
这样,我们就可以通过判断最后一个节点是否相同就可以了。
1 | bool isCross(ListNode* head1,ListNode* head2) |
假如我们还需要找出第一个公共交点,该怎么办呢?
这里,我们可以两个链表先遍历一遍得出链表的长度,然后计算长度差值L,先在长的链表上遍历L个节点,之后再同步遍历,第一个相同的节点就是第一个公共节点。