最多应用一次交换操作以获得严格递增序列

2023-12-01

我正在网上的各个网站上做一些 DS&A 问题进行练习,我遇到了这个问题:

给定一个非负整数数组,您可以从此数组中选择任何数字并交换其中的任意两位数字。如果在交换操作之后数字包含前导零,则可以省略它们并且不考虑它们。您的任务是检查是否可以最多应用一次交换操作,以便结果数组的元素严格增加。

出于某种原因,这让我一开始感到困惑,所以我去了健身房并思考了一会儿。最终我回过头来再次尝试,这次找到了解决方案。不幸的是,我得到的解决方案有点丑陋和笨重,我感觉这不是解决这个问题的好方法。它适用于我尝试过的测试,但我真的想为此找到更好的解决方案。我觉得我一定缺少一些可以改善它的基本东西。

所以我在这里发布我的代码希望得到一些反馈。

def solution(numbers):

    swaps = 0
    index = 0
    for i in range(len(numbers)-1):
        if numbers[i] >= numbers[i+1]:
            swaps+=1
            index=i
    if swaps > 1:
        return False
    elif not swaps:
        return True

    swappedI = swapToSmallest(numbers[index])
    if (index-1 < 0 or numbers[index-1] < swappedI) and numbers[index+1] > swappedI:
        return True
    swappedIPlus1 = swapToSmallest(numbers[index])
    if (index+1 > len(numbers) or numbers[index+1] < swappedIPlus1) and numbers[index-1] < swappedIPlus1:
        return True

    return False
    

def swapToSmallest(num) -> int:
    num = str(num)
    smallIndex = 0
    smallestRight = num[smallIndex]
    for i in range(1, len(num)):
        if num[i] <= smallestRight:
            smallestRight = num[i]
            smallIndex = i

    largeIndex = -1
    largeLeft = num[largeIndex]
    for i in range(len(num)-2, -1, -1):
        if num[i] >= largeLeft:
            largeLeft = num[i]
            largeIndex = i

    res = ""
    for i, v in enumerate(num):
        if i == largeIndex:
            res+=smallestRight
        elif i == smallIndex:
            res+=largeLeft
        else:
            res+=v


    return int(res)

    

#tests            
numbers = [1, 5, 10, 20]
print(solution(numbers))

numbers = [1, 3, 900, 10]
print(solution(numbers))

numbers = [1000, 10, 100]
print(solution(numbers))

numbers = [1, 2, 10, 7]
print(solution(numbers))

numbers = [1, 3, 3, 3]
print(solution(numbers))

numbers = [1000, 10, 9]
print(solution(numbers))

肯定有更简单的解决方案。例如,这是我想出的一个(只是尝试一下,我确信还有更优化的解决方案):

def flip(i):
    return int(''.join(str(i)[::-1]))


def strict_inc(xs, single_flip_allowed=True):
    for n, (a, b) in enumerate(zip(xs, xs[1:])):
        if a >= b:
            break
    else:
        return True
    # here, n will be the index at which the first problem occurs
    return single_flip_allowed and (
        (
            (n == 0 or xs[n-1] < flip(xs[n]))
            and (n == len(xs) or flip(xs[n]) < xs[n+1])
            and strict_inc(xs[n+1:], False)
        )
        or
        (
            (xs[n] < flip(xs[n+1]))
            and (n+1 == len(xs) or flip(xs[n+1]) < xs[n+2])
            and strict_inc(xs[n+2:], False)
        )
    )

(请注意,这实现了您的解决方案,并添加了翻转,但不是正确的解决方案,请继续阅读)

尽管该函数会递归调用自身,但它不会多次调用自身,因此不会出现任何问题。

它基本上工作的前提是原始正整数序列中只能有一个缺陷。因此,它找到第一个缺陷,查看是否可以通过“翻转”缺陷中的第一个或第二个整数来修复它,并检查在这种情况下序列的其余部分是否仍然严格增加(不允许进一步翻转)。

您要求对您的代码进行审查,但鉴于它显然远非最佳,因此全面完成这将是一项艰巨的任务。

如果您确实想要评论,我建议您尝试https://codereview.stackexchange.com/因为StackOverflow确实更适合寻求具体技术问题的解决方案。

事实证明(感谢@barmar 指出我的错误,并感谢@kellybundy 指出OP 的错误),一个有效的解决方案也不是那么复杂(同样有改进的空间):

def check(xs):
    x = str(xs[1])
    return any(xs[0] < int(f'{x[0:i]}{x[j]}{x[i+1:j]}{x[i]}{x[j+1:]}') < xs[2]
               for i in range(len(x)) for j in range(i+1, len(x)))


def strict_inc(xs, single_flip_allowed=True):
    for n, (a, b) in enumerate(zip(xs, xs[1:])):
        if a >= b:
            break
    else:
        return True
    # here, n will be the index at which the first problem occurs
    return single_flip_allowed and (
        (
            check(xs[n-1:n+2] if n > 0 else [-1] + xs[n:n+2])
            and strict_inc(xs[n+1:], False)
        )
        or
        (
            check(xs[n:n+3] if n < len(xs)-2 else xs[n:n+2] + [int('9'*len(str(xs[n+1])))])
            and strict_inc(xs[n+2:], False)
        )
    )

(另一个编辑:这个解决方案实际上根据需要尝试所有可能的配对)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

最多应用一次交换操作以获得严格递增序列 的相关文章

随机推荐

  • AutoFixture 约束字符串参数

    有没有一种简单的方法来指定参数 orderBy 的可能值列表 请不要一一列举 否则我也不会提问 我想指定 orderby 仅当从预定列表中选择时才有意义 假设列表非常大 仍然不是随机的 这不可能那么难 没有一个例子可以说明如此简单的任务 T
  • 单选按钮检查的更改事件未在 gridview 中触发

    我有一个网格视图 其中有一个单选按钮 我需要的是在选择单选按钮时我必须找到网格视图的数据键 还有一个问题是 我可以选择多个单选按钮 这是不应该发生的 您需要使用文字控件来注入单选按钮标记 这将处理分组 因此仅选择一个单选按钮 您无法使用标准
  • Chrome 自动化中的假地理位置

    我需要使用 python 脚本在 chrome 中自动进行地理定位 我必须伪造纬度和经度 我按照 stackoverflow 中的一些链接进行操作 但它们给出了错误 chromeDriver executeScript window nav
  • 循环运行5分钟

    我需要运行 5 分钟的 while 循环 我寻找了计时器 api 但找不到这样做 任何人都可以为此提供一个代码片段吗 Thanks 最简单的方法是检查每次迭代已经用了多少时间 例子 final long NANOSEC PER SEC 10
  • Javascript:“新日期(日期字符串)”与“新日期(年,月,日)”之间的区别

    参考这个问题的已接受答案如何在 JavaScript 中获取两个日期之间的天数 我明白了 在函数中parseDate function parseDate str var mdy str split return new Date mdy
  • 构造函数中的 C++ 引用

    我有一个类 其构造函数采用对字符串的 const 引用 该字符串充当对象的名称 因此在类实例的整个生命周期中都需要该字符串 现在想象一下如何使用这个类 class myclass public myclass const std strin
  • 尝试生成 9 位数字,每个数字都唯一

    我正在尝试获取 9 位数字 这些数字都有唯一的数字 我的第一种方法似乎有点太复杂 写起来很乏味 include
  • Facebook Open Graph 单页应用程序

    我使用主干js构建了一个单页面应用程序 我对各种应用程序状态和动态内容 例如书籍 有单独的骨干 url 路由 但本质上 Facebook 只会看到索引页面 以下问题似乎提供了一种有趣的方法来为动态内容提供物理开放图 URL 同一页面上有多个
  • 通过命令行调用laravel控制器

    在 kohana 框架中 我可以使用命令行通过命令行调用控制器 php5 index php uri controller method var1 var2 是否可以通过 cli 在 Laravel 5 中调用我想要的控制器 如果是 该怎么
  • 通过 BigCommerce API 访问 Google 购物字段

    我正在与第三方零件供应商创建自定义集成 以在 BigCommerce 的库存中创建产品 我需要能够为导入的产品打开 Google 购物并添加 MPN 和类别 但我不知道如何在 API 中修改它 如果有人有任何反馈 请告诉我 因此 在联系 B
  • 更新对象的嵌套数据数组(Redux)

    我在更新不可变的 redux 和相当嵌套的数据时遇到问题 这是我的数据结构和我想要更改的内容的示例 如果有人可以向我展示使用 ES6 和扩展运算符访问此更新的模式 我将不胜感激 const formCanvasInit id guid fi
  • 如何正确关闭客户端和服务器中的套接字(python)

    我正在用 python 编写 2 个脚本 客户端 py 服务器 py 客户端和服务器之间有一个套接字 场景是这样的 我有一个客户端要求关闭程序 因此它应该通知服务器 然后服务器将通知另一个客户端 因此我需要关闭从客户端 1 到服务器的套接字
  • Angular2 HTTP 使用 observables 订阅显示数据未定义

    我不知道我做错了什么 但不知怎的 我无法读取数据 尽管数据来自服务器响应 甚至当我放置控制台时数据也显示在服务 extractData 方法中 但是在订阅函数内的组件中 它给了我未定义的信息 帮我看看我做错了什么 我假设这是异步的问题 但是
  • 使用 WCF 服务返回 MembershipUser

    我有 WCF 服务从 ActiveDirectory 获取用户 我从请求 用户名 接收参数并使用 MembershipUser 属性创建响应 由于某种原因 联系变得紧密 服务操作找到用户并成功创建响应 执行行时 返回响应 我在客户端遇到异常
  • 无法使用 CreateJS 预加载和显示 SVG

    我正在尝试预加载一组 SVG 对象并使用 CreateJS PreloadJS 显示它们 到目前为止 我能够在不预加载的情况下显示 SVG 对象 但是一旦我使用 PreloadJS 中的 LoadQueue 我就无法让我的示例工作 有人知道
  • 在tableview中延迟加载图像

    我试图以惰性模式加载我的 uitableviewcells 的图像 我试图以最简单的方式做到这一点 我看到了很多例子 但它们超出了我的目的 这就是我目前正在做的事情 但它不起作用 Configure the cell Info info s
  • 创建 TRESTClient 时出错:“没有注册具有 guid [{}] 接口的对等点”

    我已经创建了我的类来使用 REST 我在运行时遇到 TRESTClient 组件问题 TFrwWebServiceREST class TInterfacedObject IRESTWebServiceProxy private FClie
  • 仅从 DateTime 对象获取日期或时间

    我有一个DateTime具有日期和时间的实例 如何仅提取日期或仅提取时间 var day value Date a DateTime that will just be whole days var time value TimeOfDay
  • 我应该如何在 MongoDB 中实现这个模式?

    我正在尝试编写一个跟踪脚本 但在弄清楚数据库应该如何工作方面遇到了麻烦 在 MySQL 中 我创建一个类似于以下的表 User username name string Campaign title string description s
  • 最多应用一次交换操作以获得严格递增序列

    我正在网上的各个网站上做一些 DS A 问题进行练习 我遇到了这个问题 给定一个非负整数数组 您可以从此数组中选择任何数字并交换其中的任意两位数字 如果在交换操作之后数字包含前导零 则可以省略它们并且不考虑它们 您的任务是检查是否可以最多应