链表-4

目录

657. 机器人能否返回原点G

strlen、坐标轴

 剑指 Offer 22. 链表中倒数第k个节点G

常规思路(W) :倒数第二个=正数第n-2+1个 

双指针法:快慢指针总是间隔n步长,那么当fast走到最后时,slow就指向倒数第n个节点

双指针法总结

剑指 Offer 24. 反转链表G

迭代法:注意有无头节点的区别

递归法:(别在递归里用循环啊大哥 : ) ) 

剑指 Offer 52. 两个链表的第一个公共节点G

三元运算符、判断的是指针所指节点相同(不是值相同)


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]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值