微软100题第7题(判断俩个链表是否相交)

发布一个k8s部署视频:https://edu.youkuaiyun.com/course/detail/26967

课程内容:各种k8s部署方式。包括minikube部署,kubeadm部署,kubeasz部署,rancher部署,k3s部署。包括开发测试环境部署k8s,和生产环境部署k8s。

腾讯课堂连接地址https://ke.qq.com/course/478827?taid=4373109931462251&tuin=ba64518

第二个视频发布  https://edu.youkuaiyun.com/course/detail/27109

腾讯课堂连接地址https://ke.qq.com/course/484107?tuin=ba64518

介绍主要的k8s资源的使用配置和命令。包括configmap,pod,service,replicaset,namespace,deployment,daemonset,ingress,pv,pvc,sc,role,rolebinding,clusterrole,clusterrolebinding,secret,serviceaccount,statefulset,job,cronjob,podDisruptionbudget,podSecurityPolicy,networkPolicy,resourceQuota,limitrange,endpoint,event,conponentstatus,node,apiservice,controllerRevision等。

第三个视频发布:https://edu.youkuaiyun.com/course/detail/27574

详细介绍helm命令,学习helm chart语法,编写helm chart。深入分析各项目源码,学习编写helm插件


————————————————------------------------------------------------------------------------------------------------------------------

1python版

 

'''
Created on 2017-1-17

@author: admin
第7题(链表)
微软亚院之编程判断俩个链表是否相交
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1.如果链表可能有环列?
2.如果需要求出俩个链表相交的第一个节点列?
'''
from _overlapped import NULL
class CrossList:
    def __init__(self):
        self.listA=Node()
        self.listB=Node()
        nodeA=self.listA
        nodeB=self.listB
        for i in range(0,10):
            nodeA.next=Node()
            nodeA=nodeA.next
            if i==9:
                nodeB.next=nodeA
            else:
                nodeB.next=Node()
                nodeB=nodeB.next
    def isCross(self):
        nodeA=self.listA
        nodeB=self.listB
        while nodeA!=NULL:
            while nodeB!=NULL:
                if nodeA==nodeB:
                    return True
                nodeB=nodeB.next
            nodeB=self.listB
            nodeA=nodeA.next
        return False
                
        
class Node:
    def __init__(self):
        self.next=NULL
if __name__ == '__main__':
    cl=CrossList()
    print(cl.isCross())

 

2java版

http://blog.youkuaiyun.com/hxpjava1/article/details/22210535

 

 

 

3scala版

 

package ms
/**
 * 第7题(链表) 
微软亚院之编程判断俩个链表是否相交 
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。 
为了简化问题,我们假设俩个链表均不带环。 
问题扩展: 
1.如果链表可能有环列? 
2.如果需要求出俩个链表相交的第一个节点列?
 */
class CrossList{
  var listA:Node=Node()
  var listB:Node=Node()
  def init(){
    var tmpA=listA;
    var tmpB=listB
    for(i <-0 until 10){
      tmpA.next=Node()
      tmpA=tmpA.next
      if(i==9){
        tmpB.next=tmpA
      }else{
        tmpB.next=Node()
        tmpB=tmpB.next
      }
    }
  }
  
  def isCross():Boolean={
    var tmpA=listA;
    var tmpB=listB;
    while(tmpA!=null){
      while(tmpB!=null){
        if(tmpA==tmpB){
          return  true;
        }
        tmpB=tmpB.next
      }
      tmpB=listB
      tmpA=tmpA.next
    }
    return false;
  }
}

case class Node(var next:Node=null)

object MicroSoft007 {
  
  def main(args: Array[String]): Unit = {
    var list=new CrossList()
    list.init()
    println(list.isCross())
  }
}

 

c语言版本

 

 

/*
 * microsoft007.c
 *
 *  Created on: 2017年1月26日
 *      Author: admin
 第7题(链表)
微软亚院之编程判断俩个链表是否相交
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1.如果链表可能有环列?
2.如果需要求出俩个链表相交的第一个节点列?
 */
#include <stdio.h>
#include <stdlib.h>
#define true 1
#define false 0

typedef int bool;

typedef struct LinkNode{
	int val;
	struct LinkNode * next;
}node;

void initLinkedList(int  lnk1,int  lnk2);
bool isCrosss();
static node * makeNode(int value);

node * plnk1;
node * plnk2;

int main007(){
	initLinkedList(10,10);
	bool res= isCrosss();
	if(res==true){
		printf("相交\n");
	}else{
		printf("不相交\n");
	}
	return 0;
}

void initLinkedList(int  lnk1,int  lnk2){
	node * tmp;
	for(int i=1;i<=lnk1;i++){
		if(i==1){
			plnk1=makeNode(1);
			tmp=plnk1;
		}else{
			tmp->next=makeNode(1);
			tmp=tmp->next;
		}

	}

	tmp=NULL;
	for(int i=1;i<=lnk2;i++){
		if(i==1){
			plnk2=makeNode(1);
			tmp=plnk2;
		}else{
			tmp->next=makeNode(1);
			tmp=tmp->next;
		}

	}

	tmp->next=plnk1;
}

node * makeNode(int value){
	node* p=malloc(sizeof(node));
	p->val=value;
	p->next=NULL;
	return p;
}
bool isCrosss(){
	node * tmp1=plnk1;
	node * tmp2=plnk2;
	while(tmp1!=NULL){
		bool cross=false;
		while(tmp2!=NULL){
			if(tmp1==tmp2){
				cross=true;
				break;
			}
			tmp2=tmp2->next;
		}
		if(cross){
			return true;
		}
		tmp1=tmp1->next;
	}
	return false;
}


c++版本

 

/*
 * microsoft007.cpp
 *
 *  Created on: 2017年2月6日
 *      Author: admin
 第7题(链表)
微软亚院之编程判断俩个链表是否相交
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
问题扩展:
1.如果链表可能有环列?
2.如果需要求出俩个链表相交的第一个节点列?
 */
#include "iostream"
using namespace std;

class CrossLinkNode{
public:
	CrossLinkNode(int value,CrossLinkNode*next=NULL){
		this->value=value;
		this->next=next;
	}
public:
	CrossLinkNode*& getNext()  {
		return next;
	}

	void setNext( CrossLinkNode* next) {
		this->next = next;
	}

	int getValue() {
		return value;
	}

	void setValue(int value) {
		this->value = value;
	}

private:
	int value;
	CrossLinkNode * next;
};

class CrossLink{
public:
	CrossLink(){
		linkA=new CrossLinkNode(0);
		CrossLinkNode*tmp=linkA;
		for(int i=1;i<10;i++){
			tmp->setNext(new CrossLinkNode(i));
			tmp=tmp->getNext();
		}
		linkB=new CrossLinkNode(0);
		tmp=linkB;
		for(int i=1;i<10;i++){
			tmp->setNext(new CrossLinkNode(i));
			tmp=tmp->getNext();
		}
		tmp->setNext(linkA);
	}
public:
	bool isCross(){
		CrossLinkNode*tmp=linkA;
		while(tmp!=NULL){
			CrossLinkNode*tmpB=linkB;
			while(tmpB!=NULL){
				if(tmp==tmpB){
					return true;
				}
				tmpB=tmpB->getNext();
			}
			tmp=tmp->getNext();
		}
		return false;
	}
private:
	CrossLinkNode * linkA;
	CrossLinkNode * linkB;
};

int main(){
	CrossLink link;
	cout<<(link.isCross()?"相交":"不相交")<<endl;
	return 0;
}



 

 

 

 

<think>好的,我现在需要帮助用户了解如何用Java判断两个链表是否相交。首先,我得回想一下链表相交的定义。链表相交指的是两个链表在某个节点之后合并,形成共同的部分。也就是说,从相交节点开始,后续的所有节点都是相同的,直到链表结束。 接下来,我得确定用户的需求。用户可能正在学习数据结构,或者在面试准备中遇到了这个问。他们需要具体的实现方法,而不仅仅是理论上的解释。因此,我应该提供清晰的思路和代码示例,同时考虑时间和空间复杂度。 首先,我得回顾常见的解决方法。常见的方法有两种:哈希表法和双指针法。哈希表法的思路是遍历第一个链表,将每个节点的引用存入哈希表,然后遍历第二个链表,检查是否有节点存在于哈希表中。这种方法的时间复杂度是O(m+n),空间复杂度也是O(m+n),其中m和n分别是两个链表的长度。 另一种方法是双指针法,也称为“走尾指针法”。这种方法不需要额外空间,时间复杂度同样是O(m+n)。具体步骤是:首先遍历两个链表,找到各自的尾节点,并记录长度。如果尾节点不同,说明不相交;如果相同,则计算两个链表的长度差,让较长的链表的指针先移动差值步,然后两个指针同时移动,直到相遇,相遇点即为相交节点。 用户可能更倾向于高效的方法,尤其是空间复杂度低的解决方案。因此,我应该重点解释双指针法,因为它更优。同时,我需要考虑链表可能存在的环的情况,但通常在这种情况下,目假设链表无环,所以可能不需要处理环的问,但最好在注意事项中提及。 然后,我需要考虑如何用Java实现双指针法。首先,定义链表节点的结构,通常是一个包含数据和next指针的类。然后,编写函数来检查相交。具体步骤包括遍历链表获取长度和尾节点,比较尾节点是否相同,调整指针起点,同步遍历直到找到相同节点。 在代码实现中,需要注意边界情况,例如其中一个链表为空,或者两个链表长度相差较大。此外,测试用例的构造也很重要,例如创建相交链表和不相交链表来验证代码的正确性。 可能用户还会有疑问,比如如何处理有环的情况,或者是否有其他方法。虽然问通常假设链表无环,但可以简要说明如果有环的话需要先检测环,然后再处理相交的问,但这会增加复杂度。 最后,总结思路和步骤,确保用户能够理解并实现该算法。同时,强调时间和空间复杂度,帮助用户评估不同方法的优劣。</think>--- 要判断两个链表是否相交,关键在于找到**相交节点**(两个链表的公共节点)。Java中可通过以下两种方法实现: --- ### 方法一:哈希表法 **核心思路**:遍历链表A,将所有节点存入哈希表,再遍历链表B,检查节点是否存在于哈希表中。 **时间复杂度**:$O(m + n)$,空间复杂度:$O(m)$(m、n为链表长度) ```java import java.util.HashSet; public class LinkedListIntersection { static class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public ListNode getIntersectionNode(ListNode headA, ListNode headB) { HashSet<ListNode> visited = new HashSet<>(); // 遍历链表A,存储所有节点 while (headA != null) { visited.add(headA); headA = headA.next; } // 遍历链表B,检查哈希表 while (headB != null) { if (visited.contains(headB)) { return headB; } headB = headB.next; } return null; } } ``` --- ### 方法二:双指针法(推荐) **核心思路**: 1. 若两链表相交,则**尾节点必相同** 2. 计算两链表长度差,对齐起点后同步遍历 **时间复杂度**:$O(m + n)$,空间复杂度:$O(1)$ ```java public class LinkedListIntersection { static class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) return null; // 计算链表A和B的长度 int lenA = getLength(headA), lenB = getLength(headB); // 对齐起点:长链表先走差值步 ListNode pA = headA, pB = headB; if (lenA > lenB) { for (int i = 0; i < lenA - lenB; i++) pA = pA.next; } else { for (int i = 0; i < lenB - lenA; i++) pB = pB.next; } // 同步遍历找交点 while (pA != null && pB != null) { if (pA == pB) return pA; pA = pA.next; pB = pB.next; } return null; } private int getLength(ListNode node) { int len = 0; while (node != null) { len++; node = node.next; } return len; } } ``` --- ### 方法三:巧妙双指针遍历(无长度计算) **核心思想**:两指针分别遍历A+B和B+A路径,最终会在交点相遇(若存在)。 ```java public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) return null; ListNode pA = headA, pB = headB; // 当pA和pB走过相同路径长度时: // - 若相交,会在交点相遇 // - 若不相交,最终同时为null退出循环 while (pA != pB) { pA = (pA == null) ? headB : pA.next; pB = (pB == null) ? headA : pB.next; } return pA; } ``` --- ### 验证相交的关键条件 1. **尾节点相同**:若两链表尾节点不同,则一定不相交 2. **节点引用相同**:判断相交的依据是节点对象地址相同,而非值相等 --- ### 测试用例示例 ```java public static void main(String[] args) { // 构造相交链表 ListNode common = new ListNode(8); common.next = new ListNode(4); common.next.next = new ListNode(5); ListNode headA = new ListNode(4); headA.next = new ListNode(1); headA.next.next = common; ListNode headB = new ListNode(5); headB.next = new ListNode(6); headB.next.next = new ListNode(1); headB.next.next.next = common; // 调用方法判断 ListNode result = getIntersectionNode(headA, headB); System.out.println(result != null ? "相交节点值:" + result.val : "不相交"); } ``` --- ### 复杂度对比 | 方法 | 时间复杂度 | 空间复杂度 | 适用场景 | |------------|------------|------------|--------------------| | 哈希表法 | $O(m+n)$ | $O(m)$ | 需要快速实现 | | 双指针法 | $O(m+n)$ | $O(1)$ | 内存敏感场景 | | 路径对齐法 | $O(m+n)$ | $O(1)$ | 代码简洁,无需长度 | --- ### 注意事项 1. 若链表可能有环,需先检测环再判断相交(经典相交通常假设无环) 2. 节点值可以重复,判断依据是节点引用地址相同而非值相等 3. 空链表直接返回`null`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hxpjava1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值