单链表OJ题(3)

T7 链表的回文(对称)结构

//对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为:O(1)的算法,判断其是否为回文结构。
//给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900.
//测试样例:1->2->2->1; 返回:true
//          1->2->3->2->1; 返回:true
//【先找单链表中间的结点,再逆置后半段结点,最后比较前后半段结点是否相同】

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

struct ListNode
{
	int val;
	struct ListNode* next;
};

//找链表的中间结点
struct ListNode* middleNode(struct ListNode* head)
{
	struct ListNode* slow,*fast; //定义快、慢两个指针。
	slow = fast = head;
	while (fast && fast->next) //快指针走完单链表就结束。分为奇数、偶数两种情况
	{ 
		//慢指针每次走一个,快指针每次走两个。
		slow = slow->next;
		fast = fast->next->next;
	}
	return slow; //返回慢指针指向的结点
}

//逆置链表的结点
struct ListNode* reverseList(struct ListNode* head)
{
	struct ListNode* newhead = NULL;
	struct ListNode* cur = head;
	while (cur)
	{
		struct ListNode* next = cur->next; //先保存好cur的下一个结点(地址)

		//头插
		cur->next = newhead;
		newhead = cur;

		cur = next;// cur++(向后面移动一个)
	}
	return newhead;

}

//判断链表是否是回文结构
int isPalindrome(struct ListNode* head)
{
	struct ListNode* mid = middleNode(head);
	struct ListNode* rhead = reverseList(mid);

	while (head && rhead)
	{
		if (head->val != rhead->val)
		{
			return 0;
		}
		else
		{
			head = head->next;
			rhead = rhead->next;
		}
	}
	return 1;
}


int main()
{
	struct ListNode* n1=(struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n1);
	struct ListNode* n2 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n2);
	struct ListNode* n3 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n3);
	struct ListNode* n4 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n4);
	struct ListNode* n5 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n5);
	struct ListNode* n6 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n6);
	struct ListNode* n7 = (struct ListNode*)malloc(sizeof(struct ListNode));
	assert(n7);

	n1->val = 1;
	n2->val = 2;
	n3->val = 3;
	n4->val = 4;
	n5->val = 3;
	n6->val = 2;
	n7->val = 1;

	n1->next = n2;
	n2->next = n3;
	n3->next = n4;
	n4->next = n5;
	n5->next = n6;
	n6->next = n7;
	n7->next = NULL;
	
	int ret = isPalindrome(n1);
	if (1==ret)
	{
		printf("该链表是回文结构\n");
	}
	else
	{
		printf("该链表不是回文结构\n");
	}


	free(n1);
	n1 = NULL;
	free(n2);
	n2 = NULL;
	free(n3);
	n3 = NULL;
	free(n4);
	n4 = NULL;
	free(n5);
	n5 = NULL;
	free(n6);
	n6 = NULL;
	free(n7);
	n7 = NULL;

	return 0;
}


T8 相交链表

//给你两个单链表的头结点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交结点,则返回NULL
//示范:A链表:[1,2,3]  B链表:[-2,-1,0,2,3] , 则返回相交结点2(地址)。

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

struct ListNode
{
    int val;
    struct ListNode* next;
};

struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB)
{
    struct ListNode* curA = headA, * curB = headB;
    int lenA = 1, lenB = 1;

    //求出A、B链表的长度
    while (curA->next)
    {
        curA = curA->next;
        lenA++;
    }

    while (curB->next)
    {
        curB = curB->next;
        lenB++;
    }

    //如果两条链表的最后一个结点都不相等,那么这两条两条链表无交点,则返回NULL
    if (curA != curB)
    {
        return NULL;
    }

    //求第一个交点
    //【首先,求两条链表长度的差距gap】
    struct ListNode* shortList = headA, * longList = headB;
    if (lenA > lenB)
    {
        shortList = headB;
        longList = headA;
    }
    int gap = abs(lenA-lenB);

    //【其次,长的先走gap步】
    while (gap--)
    {
        longList = longList->next;
    }
    //【最后,两条再一起走】
    while (longList != shortList) //不相等时继续一起走
    {
        longList = longList->next;
        shortList = shortList->next;
    }
    return longList; //直到相等返回相交的结点
}

int main()
{
    	//创建第一个链表
        struct ListNode* n1=(struct ListNode*)malloc(sizeof(struct ListNode));
    	assert(n1);
    	struct ListNode* n2 = (struct ListNode*)malloc(sizeof(struct ListNode));
    	assert(n2);
    	struct ListNode* n3 = (struct ListNode*)malloc(sizeof(struct ListNode));
    	assert(n3);
    	struct ListNode* n4 = (struct ListNode*)malloc(sizeof(struct ListNode));
    	assert(n4);
    	struct ListNode* n5 = (struct ListNode*)malloc(sizeof(struct ListNode));
    	assert(n5);
    	
    	n1->val = -2;
    	n2->val = -1;
    	n3->val = 0;
    	n4->val = 2;
    	n5->val = 3;
    	
    	n1->next = n2;
    	n2->next = n3;
    	n3->next = n4;
    	n4->next = n5;
        n5->next = NULL;
    	

	    //创建第二个链表
        struct ListNode* m1 = (struct ListNode*)malloc(sizeof(struct ListNode));
        assert(m1);
        m1->val = 1;
        m1->next = n4;
       
       struct ListNode* internode = getIntersectionNode(n1,m1);
       printf("%d\n",internode->val);

      free(n1);
	  n1 = NULL;
	  free(n2);
	  n2 = NULL;
	  free(n3);
	  n3 = NULL;
	  free(n4);
	  n4 = NULL;
	  free(n5);
	  n5 = NULL;

      free(m1);
      m1 = NULL;
      
      return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值