553. Optimal Division

LeetCode medium оригинал: C# #array #csharp #leetcode #math #medium #string

Дано целочисленный массив nums. Соседние целые числа в nums будут выполнять деление с плавающей запятой.

Например, для nums = [2,3,4] мы будем вычислять выражение "2/3/4".

Однако, вы можете добавить любое количество скобок в любое место, чтобы изменить приоритет операций. Вы хотите добавить эти скобки так, чтобы значение выражения после вычисления было максимальным.

Верните соответствующее выражение, которое имеет максимальное значение в строковом формате.

Пример:

Input: nums = [1000,100,10,2]

Output: "1000/(100/10/2)"

Explanation: 1000/(100/10/2) = 1000/((100/10)/2) = 200

However, the bold parenthesis in "1000/((100/10)/2)" are redundant since they do not influence the operation priority.

So you should return "1000/(100/10/2)".

Other cases:

1000/(100/10)/2 = 50

1000/(100/(10/2)) = 50

1000/100/10/2 = 0.5

1000/100/(10/2) = 2

C# решение

сопоставлено/оригинал
using System;
using System.Collections.Generic;
using System.Linq;
public class Solution {
    private List<int> AddStrings(List<int> num1, List<int> num2) {
        var ans = new List<int>();
        int carry = 0;
        int n1 = num1.Count;
        int n2 = num2.Count;
        for (int i = 0; i < Math.Max(n1, n2) + 1; ++i) {
            int digit1 = i < n1 ? num1[i] : 0;
            int digit2 = i < n2 ? num2[i] : 0;
            int sum = digit1 + digit2 + carry;
            carry = sum / 10;
            ans.Add(sum % 10);
        }
        return ans;
    }
    private List<int> MultiplyOneDigit(string firstNumber, char secondNumberDigit, int numZeros) {
        var currentResult = new List<int>(new int[numZeros]);
        int carry = 0;
        foreach (char digit in firstNumber) {
            int multiplication = (secondNumberDigit - '0') * (digit - '0') + carry;
            carry = multiplication / 10;
            currentResult.Add(multiplication % 10);
        }
        if (carry != 0) {
            currentResult.Add(carry);
        }
        return currentResult;
    }
    public string Multiply(string firstNumber, string secondNumber) {
        if (firstNumber == "0" || secondNumber == "0") {
            return "0";
        }
        firstNumber = new string(firstNumber.Reverse().ToArray());
        secondNumber = new string(secondNumber.Reverse().ToArray());
        var ans = new List<int>(new int[firstNumber.Length + secondNumber.Length]);
        for (int i = 0; i < secondNumber.Length; ++i) {
            ans = AddStrings(MultiplyOneDigit(firstNumber, secondNumber[i], i), ans);
        }
        while (ans.Last() == 0) {
            ans.RemoveAt(ans.Count - 1);
        }
        var answer = new System.Text.StringBuilder();
        for (int i = ans.Count - 1; i >= 0; --i) {
            answer.Append(ans[i]);
        }
        return answer.ToString();
    }
}

C++ решение

auto-draft, проверить перед отправкой
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    private List<int> AddStrings(List<int> num1, List<int> num2) {
        var ans = new List<int>();
        int carry = 0;
        int n1 = num1.size();
        int n2 = num2.size();
        for (int i = 0; i < max(n1, n2) + 1; ++i) {
            int digit1 = i < n1 ? num1[i] : 0;
            int digit2 = i < n2 ? num2[i] : 0;
            int sum = digit1 + digit2 + carry;
            carry = sum / 10;
            ans.push_back(sum % 10);
        }
        return ans;
    }
    private List<int> MultiplyOneDigit(string firstNumber, char secondNumberDigit, int numZeros) {
        var currentResult = new List<int>(new int[numZeros]);
        int carry = 0;
        foreach (char digit in firstNumber) {
            int multiplication = (secondNumberDigit - '0') * (digit - '0') + carry;
            carry = multiplication / 10;
            currentResult.push_back(multiplication % 10);
        }
        if (carry != 0) {
            currentResult.push_back(carry);
        }
        return currentResult;
    }
    public string Multiply(string firstNumber, string secondNumber) {
        if (firstNumber == "0" || secondNumber == "0") {
            return "0";
        }
        firstNumber = new string(firstNumber.Reverse().ToArray());
        secondNumber = new string(secondNumber.Reverse().ToArray());
        var ans = new List<int>(new int[firstNumber.size() + secondNumber.size()]);
        for (int i = 0; i < secondNumber.size(); ++i) {
            ans = AddStrings(MultiplyOneDigit(firstNumber, secondNumber[i], i), ans);
        }
        while (ans.Last() == 0) {
            ans.RemoveAt(ans.size() - 1);
        }
        var answer = new System.Text.StringBuilder();
        for (int i = ans.size() - 1; i >= 0; --i) {
            answer.Append(ans[i]);
        }
        return answer.ToString();
    }
}

Java решение

сопоставлено/оригинал
class Solution {
    private List<Integer> addStrings(List<Integer> num1, List<Integer> num2) {
        List<Integer> ans = new ArrayList<>();
        int carry = 0;
        int n1 = num1.size();
        int n2 = num2.size();

        for (int i = 0; i < Math.max(n1, n2) + 1; ++i) {
            int digit1 = i < n1 ? num1.get(i) : 0;
            int digit2 = i < n2 ? num2.get(i) : 0;
            int sum = digit1 + digit2 + carry;
            carry = sum / 10;
            ans.add(sum % 10);
        }
        return ans;
    }

    private List<Integer> multiplyOneDigit(String firstNumber, char secondNumberDigit, int numZeros) {
        List<Integer> currentResult = new ArrayList<>(Collections.nCopies(numZeros, 0));
        int carry = 0;

        for (char digit : firstNumber.toCharArray()) {
            int multiplication = (secondNumberDigit - '0') * (digit - '0') + carry;
            carry = multiplication / 10;
            currentResult.add(multiplication % 10);
        }
        if (carry != 0) {
            currentResult.add(carry);
        }
        return currentResult;
    }

    public String multiply(String firstNumber, String secondNumber) {
        if (firstNumber.equals("0") || secondNumber.equals("0")) {
            return "0";
        }

        firstNumber = new StringBuilder(firstNumber).reverse().toString();
        secondNumber = new StringBuilder(secondNumber).reverse().toString();

        List<Integer> ans = new ArrayList<>(Collections.nCopies(firstNumber.length() + secondNumber.length(), 0));

        for (int i = 0; i < secondNumber.length(); ++i) {
            ans = addStrings(multiplyOneDigit(firstNumber, secondNumber.charAt(i), i), ans);
        }

        while (ans.get(ans.size() - 1) == 0) {
            ans.remove(ans.size() - 1);
        }

        StringBuilder answer = new StringBuilder();
        for (int i = ans.size() - 1; i >= 0; --i) {
            answer.append(ans.get(i));
        }

        return answer.toString();
    }
}

JavaScript решение

сопоставлено/оригинал
class Solution {
    addStrings(num1, num2) {
        let ans = [];
        let carry = 0;
        const n1 = num1.length;
        const n2 = num2.length;

        for (let i = 0; i < Math.max(n1, n2) || carry; i++) {
            const digit1 = i < n1 ? num1[i] : 0;
            const digit2 = i < n2 ? num2[i] : 0;
            const sum = digit1 + digit2 + carry;
            carry = Math.floor(sum / 10);
            ans.push(sum % 10);
        }
        return ans;
    }

    multiplyOneDigit(firstNumber, secondNumberDigit, numZeros) {
        const currentResult = new Array(numZeros).fill(0);
        let carry = 0;

        for (const digit of firstNumber) {
            const multiplication = (secondNumberDigit * digit) + carry;
            carry = Math.floor(multiplication / 10);
            currentResult.push(multiplication % 10);
        }
        if (carry !== 0) {
            currentResult.push(carry);
        }
        return currentResult;
    }

    multiply(firstNumber, secondNumber) {
        if (firstNumber === "0" || secondNumber === "0") {
            return "0";
        }

        firstNumber = firstNumber.split('').reverse().join('');
        secondNumber = secondNumber.split('').reverse().join('');

        let ans = new Array(firstNumber.length + secondNumber.length).fill(0);

        for (let i = 0; i < secondNumber.length; i++) {
            ans = this.addStrings(this.multiplyOneDigit(firstNumber, +secondNumber[i], i), ans);
        }

        while (ans[ans.length - 1] === 0) {
            ans.pop();
        }

        return ans.reverse().join('');
    }
}

Python решение

сопоставлено/оригинал
class Solution:
    def addStrings(self, num1, num2):
        ans = []
        carry = 0
        n1, n2 = len(num1), len(num2)

        for i in range(max(n1, n2) + 1):
            digit1 = num1[i] if i < n1 else 0
            digit2 = num2[i] if i < n2 else 0
            s = digit1 + digit2 + carry
            carry = s // 10
            ans.append(s % 10)
        return ans

    def multiplyOneDigit(self, firstNumber, secondNumberDigit, numZeros):
        currentResult = [0] * numZeros
        carry = 0

        for digit in firstNumber:
            multiplication = (int(secondNumberDigit) * int(digit)) + carry
            carry = multiplication // 10
            currentResult.append(multiplication % 10)
        if carry:
            currentResult.append(carry)
        return currentResult

    def multiply(self, firstNumber, secondNumber):
        if firstNumber == "0" or secondNumber == "0":
            return "0"

        firstNumber = firstNumber[::-1]
        secondNumber = secondNumber[::-1]

        ans = [0] * (len(firstNumber) + len(secondNumber))

        for i, digit in enumerate(secondNumber):
            ans = self.addStrings(self.multiplyOneDigit(firstNumber, digit, i), ans)

        while ans[-1] == 0:
            ans.pop()

        return ''.join(map(str, ans[::-1]))

Go решение

сопоставлено/оригинал
package main

import (
    "fmt"
    "strconv"
)

func addStrings(num1 []int, num2 []int) []int {
    var ans []int
    carry := 0
    n1, n2 := len(num1), len(num2)

    for i := 0; i < max(n1, n2) || carry != 0; i++ {
        digit1, digit2 := 0, 0
        if i < n1 {
            digit1 = num1[i]
        }
        if i < n2 {
            digit2 = num2[i]
        }
        sum := digit1 + digit2 + carry
        carry = sum / 10
        ans = append(ans, sum%10)
    }
    return ans
}

func multiplyOneDigit(firstNumber string, secondNumberDigit rune, numZeros int) []int {
    var currentResult []int
    for i := 0; i < numZeros; i++ {
        currentResult = append(currentResult, 0)
    }
    carry := 0

    for _, digit := range firstNumber {
        multiplication := (int(secondNumberDigit-'0') * int(digit-'0')) + carry
        carry = multiplication / 10
        currentResult = append(currentResult, multiplication%10)
    }
    if carry != 0 {
        currentResult = append(currentResult, carry)
    }
    return currentResult
}

func multiply(firstNumber string, secondNumber string) string {
    if firstNumber == "0" || secondNumber == "0" {
        return "0"
    }

    firstNumberRev := reverseString(firstNumber)
    secondNumberRev := reverseString(secondNumber)

    ans := make([]int, len(firstNumber)+len(secondNumber))

    for i, digit := range secondNumberRev {
        ans = addStrings(multiplyOneDigit(firstNumberRev, digit, i), ans)
    }

    for len(ans) > 1 && ans[len(ans)-1] == 0 {
        ans = ans[:len(ans)-1]
    }

    result := ""
    for i := len(ans) - 1; i >= 0; i-- {
        result += strconv.Itoa(ans[i])
    }

    return result
}

func reverseString(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func main() {
    fmt.Println(multiply("123", "456"))
}

Algorithm

Разверните оба числа. Инициализируйте массив ans с (N+M) нулями. Для каждой цифры во втором числе: держите переменную переноса, изначально равную 0. Инициализируйте массив (currentResult), начинающийся с некоторых нулей в зависимости от места цифры во втором числе.

Для каждой цифры первого числа: умножьте цифру второго числа на цифру первого числа и добавьте предыдущий перенос к результату умножения. Возьмите остаток от деления на 10, чтобы получить последнюю цифру. Добавьте последнюю цифру к массиву currentResult. Разделите результат умножения на 10, чтобы получить новое значение переноса.

После итерации по каждой цифре в первом числе, если перенос не равен нулю, добавьте перенос к массиву currentResult. Добавьте currentResult к массиву ans. Если последняя цифра в ans равна нулю, перед разворотом ans удалите этот ноль, чтобы избежать ведущего нуля в окончательном ответе. Разверните ans и верните его.

😎

Вакансии для этой задачи

Показаны активные вакансии с пересечением по тегам задачи.

Все вакансии
Активных вакансий пока нет.