目录
双指针法:快慢指针总是间隔n步长,那么当fast走到最后时,slow就指向倒数第n个节点
657. 机器人能否返回原点
- 在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。
- 移动顺序由字符串表示。字符 move[i] 表示其第 i 次移动。机器人的有效动作有 R(右),L(左),U(上)和 D(下)。如果机器人在完成所有动作后返回原点,则返回 true。否则,返回 false。
- 注意:机器人“面朝”的方向无关紧要。 “R” 将始终使机器人向右移动一次,“L” 将始终向左移动等。此外,假设每次移动机器人的移动幅度相同。
### 解题思路
strlen、坐标轴
执行用时:4 ms, 在所有 C 提交中击败了97.87%的用户
内存消耗:5.5 MB, 在所有 C 提交中击败了91.15%的用户
### 代码
```c
bool judgeCircle(char * moves){
int n=strlen(moves),x=0,y=0;
for(int i=0;i<n;i++){
if(moves[i]=='U') y++;
if(moves[i]=='D') y--;
if(moves[i]=='R') x++;
if(moves[i]=='L') x--;
}
return (x==0&&y==0);
}
```
剑指 Offer 22. 链表中倒数第k个节点
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。
常规思路(W) :倒数第二个=正数第n-2+1个
-
执行用时:4 ms, 在所有 C 提交中击败了49.88%的用户
内存消耗:5.5 MB, 在所有 C 提交中击败了18.12%的用户
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* getKthFromEnd(struct ListNode* head, int k){
struct ListNode *p=head;
int size=0;
while(p){
size++;
p=p->next;
}
size=size-k;
while(size--){
head=head->next;
}
return head;
}
双指针法:快慢指针总是间隔n步长,那么当fast走到最后时,slow就指向倒数第n个节点
双指针法总结
- 双指针法的关键在于,一个指针快一个指针慢,他们之间的间隔由具体题目决定,
- 环形链表:low步长1,fast步长是2(这种安排时:快指针走到最后,慢指针恰好在链表中间),两个指针慢慢拉开差距,只要两个指针快慢不同有环必然相遇
- 回文链表:快慢指针应用于确定后半个链表
- 得到链表的中间节点:同环形链表:fast最后时,中间节点就是slow
- 本题(链表的倒数第n个节点):步长n确定fast位置,然后slow和fast开始步长为1移动,快慢指针总是间隔n步长,那么当fast走到最后时,slow就指向倒数第n个节点
- (while(k=3),printf 2-1-0,循环3次)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* getKthFromEnd(struct ListNode* head, int k){
struct ListNode *f=head,*s=head;
while(k--) f=f->next;//确定步长(while(k=3),printf 2-1-0,循环3次)
while(f){
s=s->next;
f=f->next;
}
return s;
}
剑指 Offer 24. 反转链表
迭代法:注意有无头节点的区别
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
struct ListNode *p=head,*temp;
head=NULL;//该==的时候不==,不该==的时候乱==
//注意,无头结点
while(p){
temp=p->next;
p->next=head;
head=p;
p=temp;
}
return head;
}
递归法:(别在递归里用循环啊大哥 : ) )
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
if(!head) return NULL; //递归里必须判断,否则空指针错误
struct ListNode *p=head;
while(!p->next) return head; //必须有递归结束条件
struct ListNode *new_head=reverseList(p->next);//别在递归算法里用循环啊大哥
p->next->next=p;
p->next=NULL;
return new_head;
}
剑指 Offer 52. 两个链表的第一个公共节点
三元运算符、判断的是指针所指节点相同(不是值相同)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if(!headA||!headB) return NULL; //注意看题目,题目说了这种情况,别忘了
struct ListNode *p=headA,*q=headB;
while(p!=q){ //不相交的两个链表则都会变空指针,空指针相等结束循环
p=p==NULL?headB:p->next; //别错写成p=p->next
q=q==NULL?headA:q->next;
}
return p;
}
[17, 23, 15, 30, 21, 5, 20, 14, 5, 9, 22, 6, 22, 20, 14, 12, 4, 21, 27, 5, 4, 21, 27, 0, 14, 21, 17, 27, 6, 12, 28, 17, 29, 8, 17, 13, 7, [17, 23, 15, 30, 21, 5, 20, 14, 9, 22, 6, 12,4, 27, 27,0,28,29,8,13,7,26,31,31,19,10,16,24,2,3]
[17,23, 15, 30, 21, 5, 20, 14, 9, 22, 6, 12,4 , 27, 0,28,29,8,13,7,26,31,19,10,16,24,2,3]
[17,23,15,30,21,5,20,14,9,22,6,12,4,27,27,0,28,29,8,13,7,26,31,31,19,10,16,24,2,3]