[leetcode 周赛 160] 1237 找出给定方程的正整数解

1237 Find Positive Integer Solution for a Given Equation 找出给定方程的正整数解

问题描述

给出一个函数 f(x, y) 和一个目标结果 z,请你计算方程 f(x,y) == z 所有可能的正整数 数对 xy

给定函数是严格单调的,也就是说:

  • f(x, y) < f(x + 1, y)
  • f(x, y) < f(x, y + 1)

函数接口定义如下:

interface CustomFunction {
public:
  // Returns positive integer f(x, y) for any given positive integer x and y.
  int f(int x, int y);
};

如果你想自定义测试,你可以输入整数 function_id 和一个目标结果 z 作为输入,其中 function_id 表示一个隐藏函数列表中的一个函数编号,题目只会告诉你列表中的 2 个函数。

你可以将满足条件的 结果数对 按任意顺序返回。

示例 1:

输入: function_id = 1, z = 5
输出: [[1,4],[2,3],[3,2],[4,1]]
解释: function_id = 1 表示 f(x, y) = x + y

示例 2:

输入: function_id = 2, z = 5
输出: [[1,5],[5,1]]
解释: function_id = 2 表示 f(x, y) = x * y

提示:

  • 1 <= function_id <= 9
  • 1 <= z <= 100
  • 题目保证 f(x, y) == z 的解处于 1 <= x, y <= 1000 的范围内。
  • 1 <= x, y <= 1000 的前提下,题目保证 f(x, y) 是一个 32 位有符号整数。

思路

  • 读题
    给定一个黑盒函数, 它的特点是严格递增, 找到函数结果为输入值的(x, y)对

暴力法

读题可知, 函数由输入结果z划分, 固定x值, 遍历y值, 直到找到结果则终止, x+1进入下一次遍历

暴力法+二分

读题可知, 每个x值的直线与结果z直线只有一个交点, 而这个交点的y值符合二分遍历的特性
固定x值: (x, my-1) < (x, my)=z < (x, my+1)
(二分在一个有序数组中查找特定元素)

代码实现

暴力法

class Solution {
    public List<List<Integer>> findSolution(CustomFunction customfunction, int z) {
        List<List<Integer>> ans = new ArrayList<>();

        // x,y 的取值范围[1, 1000]
        int size = 1000;
        for (int x = 1; x <= size; x++) {
            for (int y = 1; y <= size; y++) {
                int cur = customfunction.f(x, y);
                if (cur == z) {
                    ans.add(Arrays.asList(x, y));
                } else if (cur > z) {
                    // 函数是严格单调
                    break;
                }
            }
        }

        return ans;
    }
}

暴力+二分

class Solution {
    public List<List<Integer>> findSolution(CustomFunction customfunction, int z) {
        // 符合一个二分的特性 最终结果z: 固定某一x (x, my-1)<(x, my)=z<(x, my+1)
        int size = 1000;
        List<List<Integer>> ans = new ArrayList<>();
        for (int x = 1; x < size; x++) {
            if (customfunction.f(x, 1) > z) {
                break;
            }
            // 通过二分查找 在一个`递增数列`中
            int lo = 1, hi = size;
            while (lo < hi) {
                int my = (lo + hi) / 2;
                int cur = customfunction.f(x, my);
                if (cur > z) {
                    hi = my;
                } else if (cur < z) {
                    lo = my + 1;
                } else {
                    // cur == z 查找到 直接跳出
                    ans.add(Arrays.asList(x, my));
                    break;
                }
            }
        }

        return ans;
    }
}

参考资源

第 160 场周赛 全球排名

原文地址:https://www.cnblogs.com/slowbirdoflsh/p/11781029.html

时间: 2024-11-02 13:08:50

[leetcode 周赛 160] 1237 找出给定方程的正整数解的相关文章

leetcode-160场周赛-5238-找出给定方程的正整数解

题目描述: class Solution: def findSolution(self, customfunction: 'CustomFunction', z: int) -> List[List[int]]: res = [] for i in range(1,1001): for j in range(1,1001): if customfunction.f(i,j) == z: res.append([i,j]) if customfunction.f(i,j) > z: break

(算法:二分查找)在排序数组中,找出给定数字出现的次数

题目: 在排序数组中,找出给定数字出现的次数 思路: 既然出现排序数组,很容易想到二分查找,时间复杂度为O(logn): 先通过二分查找找到最左边出现该数字的下标left(如果没找到,则返回-1),然后通过二分查找找到最右边出现该数字的下表right(如果没找到,则返回-1),然后right-left+1就是出现的次数: 代码: #include <iostream> using namespace std; int BinarySearchCount(int *array,int len,i

9.11排序与查找(五)——有个排序后的字符串数组,其中散布着一些空字符串,找出给定字符串的位置

/** * 功能:有个排序后的字符串数组,其中散布着一些空字符串,找出给定字符串的位置. */ /** * 思路:对二分查找法做修改,与mid比较的地方,如果mid为空字符串,则将mid换到离它最近的非空字符串的位置. * @param strings * @param str * @return */ public static int search(String[] strings,String str){ if(strings==null||str==null||str=="")

循环-13. 求特殊方程的正整数解

循环-13. 求特殊方程的正整数解(15) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 张彤彧(浙江大学) 本题要求对任意给定的正整数N,求方程X2+Y2=N的全部正整数解. 输入格式: 输入在一行中给出正整数N(<=10000). 输出格式: 输出方程X2+Y2=N的全部正整数解,其中X<=Y.每组解占1行,两数字间以1空格分隔,按X的递增顺序输出.如果没有解,则输出“No Solution”. 输入样例1: 884 输出

循环-13. 求特殊方程的正整数解(15)

1 #include<iostream> 2 #include<iomanip> 3 #include<cmath> 4 using namespace std; 5 int main(){ 6 int i,n,flag=1; 7 cin>>n; 8 for(i=1;i<=sqrt(n/2);++i) 9 if(sqrt(n-pow(i,2))==int(sqrt(n-pow(i,2)))){ 10 cout<<i<<"

LeetCode:Consecutive Numbers - 找出连续出现的数字

1.题目名称 Consecutive Numbers(找出连续出现的数字) 2.题目地址 https://leetcode.com/problems/consecutive-numbers/ 3.题目内容 写一个SQL,查出表Logs中连续出现至少3次的数字: +----+-----+ | Id | Num | +----+-----+ | 1  |  1  | | 2  |  1  | | 3  |  1  | | 4  |  2  | | 5  |  1  | | 6  |  2  | | 

位运算 找出给定的数中其他数都是两个,有两个是一个的数

题目大意: 给定你n个数, 其中有n-2个数都是两两成对的,有两个是单独出现的,如n = 8, 2 3 2 5 3 6 4 6, 这时候4和5是单独的两个,所以答案就是4,5,其中n的范围是1e6. 思路: 之前做过找一个单独的数的题,那个题是用一个比较巧妙的方法来做的,不过这个也是一类经典问题,用到了强大的位运算,有了那个题的基础再来做这个题就简单了.(附:找一个的题目链接). 刚开始我是用了O(nlogn)的时间复杂度来做的,先排序,然后用类似找一个的方法找出第二个.我觉得对于1e6的数据量

LeetCode 16 3Sum Closest 找出最接近指定target的三个数的和

题目: Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution. For example, given array S = {-

找出给定的一个字符串中最大的不重复子串,不重复子串即一个子串中不出现两个相同的字符

思路一:先找出一个字符串中所有子串,再找出所有子串中最长的那一个:思路二:每次找出的子串长度都比上一次的子串长,则最后的子串即是最长子串的长度数.我选择的是第二种方法. public class FindSubstringMaxlengthNoduplicate { public static void main(String[] args) { String s = "adcdghcwioizhfksjdyuiodfhjskhgkhgeisdcjdkh"; ArrayList<