反转链表:
1. 用头插来实现
2. 用栈来实现(递归)
3. 三个指针,一个表示本节点,一个表示前驱,一个表示后继
找链表的入环点:
第一步确认是否有环:
方法:快慢指针:
一个走得快,一个走的慢,当慢的能追上快的就是有环
如果当走得快的走到了结尾,则表示没环。
第二步找入环点:
方法1. 一个指针先从头走环的大小个步,然后第二个和第一个一起走,则相遇时就是入环点
方法2. 快慢指针相遇点到入环点的距离==从头开始到入环点的距离
确定是否有环的代码如下:
ListNode* MeetingNode(ListNode* pHead) //找是否有环
{
if (pHead == NULL)
return NULL;
ListNode *pslow = pHead->next;//慢
if (pslow == NULL)
return NULL;
ListNode* pfast = pslow->next;//快
while (pfast != NULL && pfast->next != NULL)
{
if (pslow == pfast)
return pslow;
pslow = pslow->next;
pfast = pfast->next->next;
}
return NULL;
}
找链表的倒数第k个节点:
分析:
方法1,先计算链表长度,在找第k个节点
方法2. 两个指针,一个先走k-1步;第k步开始时,两个指针一块走;当先走的到尾时,则后走的所在位置就是第 k个节点
注意:链表可能总长度都不为 k,所以针对这个情况要处理
代码实现如下:
ListNode *FindKthToTail(ListNode* plist, unsigned int k)
{
if (plist == NULL || k == 0)
return NULL;
ListNode *pAheaad = plist;
ListNode *pBehind = NULL;
int i = 0;
for (unsigned int i = 0; i < k - 1; i++) //先走k-1步
{
if (pAheaad->next != NULL)
pAheaad = pAheaad->next;
else //链表长度没有k-1长度个
return NULL;
}
pBehind = plist;
while (pAheaad->next != NULL) //后续还有数据
{
pBehind = pBehind->next;
pAheaad = pAheaad->next;
}
return pBehind; //返回后走的节点,即为倒数第k个节点
}
使得数组中奇数位于偶数之前:
分析:使用二分的思想
代码实现:
void reOrderArray(int *arr, int len)
{
int index1 = 0;
int index2 = len - 1;
while (index1 < index2)
{
while (index1 < index2 && (arr[index1] & 0x1) == 1)
index1++;
while (index1 < index2 && (arr[index2] & 0x1) == 0)
index2--;
if (index1 < index2)
{
int tmp = arr[index1];
arr[index2] = arr[index1];
arr[index1] = tmp;
}
}
}
扩展:我们可以通过函数指针来是实现范式,使得此代码的结构不变情况下完成更多的不同需求"分边"任务。