[leetcode]Intersection of Two Linked Lists寻找两链表的公共节点

Write a program to find the node at which the intersection of two singly linked lists begins.

For example, the following two linked lists:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3

begin to intersect at node c1.

Notes:
If the two linked lists have no intersection at all, return null.
The linked lists must retain their original structure after the function returns.
You may assume there are no cycles anywhere in the entire linked structure.
Your code should preferably run in O(n) time and use only O(1) memory.
题目意思:求两链表的第一个公共节点出现的位置,并把该位置的节点返回。
notes:
如果两个链表根本没有交集,返回null。
链表函数返回后,保留其原有的结构返回。
你可以假设没有循环在整个地方的连接结构。
您的代码应该优选地运行在O(n)时间和O(1)的存储。
解题思路:
1. 把链表变换为反向链表,通过比较最后两个链表的节点值的不同来搜索出第一个公共节点,但与题目给出的要求“保留原有结构不符”
2. 若两个链表的最后一个元素相等,则这两个链表一定存在公共节点,也许公共节点是最后第二个,也许是链表中间的某一个节点,让长的链表先移动abs(sizeA-sizeB)距离,让headA与headB的长度一致,这样就容易比较两个链表并寻的第一个公共节点。
如下为思路2的C代码,比较冗余:

/**
 * 解题思路:headA与headB的链表长度有三种情况,1. headA长度比headB长 2. headA长度比headB短  3.headA的长度 == headB的长度
 * 若两个链表的最后一个元素ListNODE是相等的,说明这两个链表一定相等,只是不清楚相等的第一个元素在链表的那个位置
 *所以我们可以采取如下思路:长的链表先移动abs(sizeA-sizeB)个节点,这样headA与headB一样长,就可以进行两链表直接对比
 * 寻找节点相等的公共节点
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {

    int i,sizeA,sizeB;
    int sub = 0;
    struct ListNode *A, *B;
    A = headA;
    B = headB;
    if(headA == NULL || headB == NULL){
        return NULL;
    }
    sizeA = 1;
    while(headA->next != NULL){
        sizeA++;
        headA = headA->next;
    }
    sizeB = 1;
    while(headB->next != NULL){
        sizeB++;
        headB = headB->next;
    }
    if(headA->val == headB->val){
        if(sizeA > sizeB){
            sub = sizeA - sizeB;
            for(i = 0; i < sub; i++){
                A = A->next;
            }
        }else if(sizeA < sizeB){
            sub = sizeB - sizeA;
            for(i = 0; i < sub; i++){
                B = B->next;
            }
        }
        while(A != NULL && B != NULL){
            if(A->val == B->val){
                return A;
            }else{
                A = A->next;
                B = B->next;
            }
        }
    }else{
        return NULL;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本题要求合并个有序链表。对于链表中的每一个节点,由于链表是有序的,所以可以将链表中的节点按照大小顺序进行比较,然后逐个将较小的节点链接上去,最终得到一个新的有序链表。 使用Rust语言实现这个问题,需要首先定义一个链表节点的结构体,包含node值以及next指针。然后定义一个函数来合并个有序链表,输入为链表的头节点指针,输出为新的有序链表的头节点指针。 在合并过程中,首先需要判断链表的头节点哪一个较小,将较小的节点作为新链表的头节点,并将该节点的next指针指向递归调用合并函数的结果。递归结束条件为其中一个链表为空,则将另一个链表直接链接到新链表上。 完整代码如下: ```rust // 定义链表节点结构体 #[derive(Debug)] struct ListNode { val: i32, next: Option<Box<ListNode>>, } impl ListNode { fn new(val: i32) -> Self { ListNode { val, next: None } } } // 合并个有序链表 fn merge_two_lists(l1: Option<Box<ListNode>>, l2: Option<Box<ListNode>>) -> Option<Box<ListNode>> { match (l1, l2) { (None, None) => None, // 链表均为空 (l1, None) => l1, // 其中一个链表为空,直接返回另一个链表 (None, l2) => l2, (Some(mut l1), Some(mut l2)) => { if l1.val < l2.val { l1.next = merge_two_lists(l1.next, Some(l2)); Some(l1) } else { l2.next = merge_two_lists(Some(l1), l2.next); Some(l2) } } } } // 测试代码 fn main() { let l1 = Some(Box::new(ListNode { val: 1, next: Some(Box::new(ListNode { val: 2, next: Some(Box::new(ListNode { val: 4, next: None, })), })), })); let l2 = Some(Box::new(ListNode { val: 1, next: Some(Box::new(ListNode { val: 3, next: Some(Box::new(ListNode { val: 4, next: None, })), })), })); let merged = merge_two_lists(l1, l2); println!("{:?}", merged); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值