【算法】力扣【链表、gcd、py3、cpp、java、js】2807. 在链表中插入最大公约数

2807. 在链表中插入最大公约数


【算法】力扣【链表、gcd、py3、cpp、java、js】2807. 在链表中插入最大公约数

题目描述

给你一个链表的头 head,每个结点包含一个整数值。在相邻结点之间,请你插入一个新的结点,结点值为这两个相邻结点值的最大公约数。请你返回插入之后的链表。两个数的最大公约数是可以被两个数字整除的最大正整数。

示例

示例 1:

输入:

head = [18,6,10,3]

输出:

[18,6,6,2,10,1,3]

解释:
第一幅图是一开始的链表,第二幅图是插入新结点后的图(蓝色结点为新插入结点)。

  • 18 和 6 的最大公约数为 6,插入第一和第二个结点之间。
  • 6 和 10 的最大公约数为 2,插入第二和第三个结点之间。
  • 10 和 3 的最大公约数为 1,插入第三和第四个结点之间。
    所有相邻结点之间都插入完毕,返回链表。

示例 2:

输入:

head = [7]

输出:

[7]

解释:
第一幅图是一开始的链表,第二幅图是插入新结点后的图(蓝色结点为新插入结点)。
没有相邻结点,所以返回初始链表。

提示:

  • 链表中结点数目在 [1, 5000] 之间。
  • 1 <= Node.val <= 1000

解释

小学数学 + 链表题。按照题意模拟即可。

解法

Python

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
from math import gcd
class Solution:
    def insertGreatestCommonDivisors(self, head: Optional[ListNode]) -> Optional[ListNode]:
        right = head.next
        left = head

        while right is not None:
            # 生成当前相邻节点的gcd节点
            left_val, right_val = left.val, right.val
            _gcd = gcd(left_val, right_val)
            gcd_node = ListNode(_gcd)

            # 插入gcd节点
            left.next = gcd_node
            gcd_node.next = right

            # 走向下一对相邻节点
            left = right
            right = right.next
        return head

JavaScript

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var insertGreatestCommonDivisors = function(head) {
        right = head.next;
        left = head;

        while (right != null) {
            // 生成当前相邻节点的gcd节点
            left_val = left.val;
            right_val = right.val;
            _gcd = gcd(left_val, right_val);
            gcd_node = new ListNode(_gcd);

            // 插入gcd节点
            left.next = gcd_node;
            gcd_node.next = right;

            // 走向下一对相邻节点
            left = right;
            right = right.next;
        }
        return head;
};

function gcd(a, b) {
    while (a != 0) {
        temp = a;
        a = b % a;
        b = temp;
    }
    return b;
}

C++

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* insertGreatestCommonDivisors(ListNode* head) {
        ListNode *left = head, *right = head->next;
        while (right != nullptr) {
            int left_val = left->val, right_val = right->val;
            auto gcd_node = new ListNode(gcd(left_val, right_val));
            left->next = gcd_node;
            gcd_node->next = right;
            left = right;
            right = right->next;
        }
        return head;
    }
};

Java

import java.math.BigInteger;

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode insertGreatestCommonDivisors(ListNode head) {
        ListNode left = head, right = head.next;

        while (right != null) {
            // 生成当前相邻节点的gcd节点
            BigInteger left_val = BigInteger.valueOf(left.val);
            BigInteger right_val = BigInteger.valueOf(right.val);
            BigInteger gcd_result = left_val.gcd(right_val);
            ListNode gcd_node = new ListNode(gcd_result.intValue());

            // 插入gcd节点
            left.next = gcd_node;
            gcd_node.next = right;

            // 走向下一对相邻节点
            left = right;
            right = right.next;
        }
        return head;
    }
}

复杂度分析

时间复杂度: O ( n ) O(n) O(n),其中 n n n 是链表的长度。

空间复杂度: O ( 1 ) O(1) O(1),只使用常数级别的额外空间。

  • 36
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值