问题描述
给你一个链表的头 head
,每个结点包含一个整数值。
在相邻结点之间,请你插入一个新的结点,结点值为这两个相邻结点值的 最大公约数 。
请你返回插入之后的链表。
两个数的 最大公约数 是可以被两个数字整除的最大正整数。
EX1.
输入:head = [18,6,10,3] 输出:[18,6,6,2,10,1,3] 解释:第一幅图是一开始的链表,第二幅图是插入新结点后的图(蓝色结点为新插入结点)。 - 18 和 6 的最大公约数为 6 ,插入第一和第二个结点之间。 - 6 和 10 的最大公约数为 2 ,插入第二和第三个结点之间。 - 10 和 3 的最大公约数为 1 ,插入第三和第四个结点之间。 所有相邻结点之间都插入完毕,返回链表。
EX2.
输入:head = [7] 输出:[7] 解释:第一幅图是一开始的链表,第二幅图是插入新结点后的图(蓝色结点为新插入结点)。 没有相邻结点,所以返回初始链表。
代码实现
C语言:
/*
//Definition for singly-linked list:
//单链表结构体定义
struct ListNode
{
int val;
struct ListNode *next;
};
*/
//重命名结构体struct ListNode:后面不用再写struct ListNode,而是直接写ListNode
typedef struct ListNode ListNode;
//函数体实现寻找两个数x,y的最大公约数
int get_value(int x, int y)
{
while (y != 0)
//y不为0时循环,y为0时最大公约数即为x
//循环找出最大公约数
{
int tmp = x % y;
x = y;
y = tmp;
}
return x;
}
//函数体实现创造新的链表节点
ListNode* creat_list_node(int val)
{
ListNode* newNode = (ListNode*) malloc (sizeof(ListNode));
//动态内存分配:需要时才会声明,才会分配一块大小为ListNode的内存
newNode->val = val;//新节点的val=传入参数val
newNode->next = NULL;//新节点的next=NULL
return newNode;//返回新节点
}
//函数体实现在两个节点之间插入节点
struct ListNode* insertGreatestCommonDivisors(struct ListNode* head)
{
ListNode * node = head;//创造一个变量链表,先使其等于输入的参数的表头head
while (node->next != NULL) {
ListNode *newNode = creat_list_node(get_value(node->val,node->next->val));//创造一个新的结点,使其值为相邻两个结点的最大公约数
newNode->next = node->next;//使新节点指向下一结点
node->next = newNode;//使上一个结点指向新结点
node = newNode->next;//使node指向下一个,重复循环
}
return head;//返回head
}
总结
这个题目对我来说有点难了...前后理解了近一个小时才有点眉目,毕竟上学期刚刚学完C语言,而且链表这一块学校没有讲,幸好之前有自学过,貌似很多算法题都有用到链表知识,这个题还算比较好理解的,就是一次一次的插值,不停迭代。