学会LeetCode三道题

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、左旋转字符串
      • 1.题目描述
      • 2.解题思路
  • 二、回文链表
      • 1.题目描述
      • 2.解题思路
  • 三、两个链表第一个公共节点
      • 1.题目描述
      • 2.解题思路
  • 总结


前言


学会LeetCode三道题_第1张图片

一、左旋转字符串

左旋转字符串

1.题目描述

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
学会LeetCode三道题_第2张图片学会LeetCode三道题_第3张图片

2.解题思路

方法1:定义临时变量,两个循环,此方法效率比较低。

代码如下:

#include
char* reverseLeftWords(char* s, int n)
{
     
    int len=strlen(s);
    n=n%len;
    int i=0;
    int j=0;
    for(i=0;i<n;i++)  //旋转n个,
    {
     
        char tmp=*s;        //定义一个临时变量
        for(j=0;j<len-1;j++)//旋转一个
        {
     
            *(s+j)=*(s+j+1);
        }
        *(s+len-1)=tmp;
    }
    return s;
}
int main()
{
     
	int k = 0;
	char arr[] = "bit education";
	int len = strlen(arr);
	scanf("%d", &k);
	left_move1(arr, k,len);
	printf("%s\n", arr);
	return 0;
}

方法2:把字符串分为两个部分,一部分k前面的字符,一部分k后面的字符,先旋转前面字符,再旋转后面字符,再整体旋转。
代码如下:

void reverse(char* left, char* right)       //方法2
{
     
	assert(left&&right);
	while (left < right)
	{
     
		char tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}
char* left_move2(char* arr, int k)
{
     
	assert(arr);
	int len = strlen(arr);
	reverse(arr, arr + k - 1);
	reverse(arr + k, arr + len - 1);
	reverse(arr, arr + len - 1);
	return arr;
}
int main()
{
     
	int k = 0;
	char arr[] = "bit education";
	int len = strlen(arr);
	scanf("%d", &k);
	left_move2(arr, k);
	printf("%s\n", arr);
	return 0;
}

二、回文链表

回文链表

1.题目描述

请判断一个链表是否为回文链表。
学会LeetCode三道题_第4张图片
在这里插入图片描述

2.解题思路

学会LeetCode三道题_第5张图片
思路二的效率更高,所以实现思路二:

  1. 先找到中间节点
  2. 中间节点后半部分逆置
  3. 比较前面和后面的节点
    代码如下:
#define _CRT_SECURE_NO_WARNINGS   1
#include
#include
struct ListNode
{
     
	int val;
	struct ListNode* next;
};
struct ListNode* middleNode(struct ListNode* head)
{
     
	struct ListNode* fast = head, *slow = head;
	while (fast&&fast->next)
	{
     
		fast = fast->next->next;
		slow = slow->next;
	}
	return slow;
}
struct ListNode* reverse(struct ListNode* head)
{
     
	struct ListNode* cur = head;
	struct ListNode* newhead = NULL;
	while (cur)
	{
     
		struct ListNode* next = cur->next;
		cur->next = newhead;
		newhead = cur;
		cur = next;
	}
	return newhead;
}
bool isPalindrome(struct ListNode* head)
{
     
	struct ListNode* mid = middleNode(head);
	struct ListNode* rhead = reverse(mid);
	while (head&&rhead)
	{
     
		if (head->val != rhead->val)
		{
     
			return false;
		}
		else
		{
     
			head = head->next;
			rhead = rhead->next;
		}
	}
	return true;
}

三、两个链表第一个公共节点

两个链表第一个公共结点

1.题目描述

输入两个链表,找出它们的第一个公共节点。
学会LeetCode三道题_第6张图片
学会LeetCode三道题_第7张图片
学会LeetCode三道题_第8张图片
学会LeetCode三道题_第9张图片

2.解题思路

  1. 计算两个链表的长度
  2. 计算两个链表相差的长度
  3. 长度更长的链表先走更长的相差长度,再一同走,第一次相遇则是公共节点
    学会LeetCode三道题_第10张图片
    代码如下:
#define _CRT_SECURE_NO_WARNINGS   1
#include
#include
struct ListNode
{
     
	int val;
	struct ListNode* next;
};
//1.求出两个链表的长度
//2.比较两个链表谁更长
//3.求出两个链表的相差的长度
//4.长的链表先走相差的长度,然后两链表一起走完
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
     
	if (headA == NULL || headB == NULL)
	{
     
		return NULL;
	}
	struct ListNode* curA = headA, *curB = headB;
	int lenA = 0;
	int lenB = 0;
	while (curA->next)  //如果curA是空链表,则程序崩溃
	{
     
		lenA++;
		curA = curA->next;
	}
	while (curB->next)
	{
     
		lenB++;
		curB = curB->next;
	}
	if (curA != curB)
	{
     
		return NULL;
	}
	struct ListNode* longList = headA, *shortList = headB;
	if (lenB > lenA)
	{
     
		longList = headB;
		shortList = headA;
	}
	int gap = abs(lenA - lenB);
	while (gap--)
	{
     
		longList = longList->next;
	}
	while (longList != shortList)
	{
     
		longList = longList->next;
		shortList = shortList->next;
	}
	return longList;
}
int main()
{
     
	return 0;
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍了链表的使用和左旋字符串,这些题目可能以后面试时会用到,我们务必掌握。另外,如果上述有任何问题,请懂哥指教,不过没关系,主要是自己能坚持,更希望有一起学习的同学可以帮我指正,但是如果可以请温柔一点跟我讲,爱与和平是永远的主题,爱各位了。
学会LeetCode三道题_第11张图片

你可能感兴趣的:(c,数据结构,算法,链表,leetcode,算法)