鱼C论坛

 找回密码
 立即注册
查看: 6555|回复: 83

[已解决]Python:每日一题 279

[复制链接]
发表于 2019-11-22 22:39:26 | 显示全部楼层 |阅读模式
20鱼币
本帖最后由 zltzlt 于 2019-11-23 08:31 编辑

今天的题目:


给定一个整数 n,返回比它小的数。这个数有如下要求:
1. n 的位数可以交换,但是不能修改。例如 21,你可以将 1 和 2 交换,得到 12,但不能用 2 - 1 得到 11
2. 当你找不到一个比 n 小的整数时,返回 -1
3. 当 0 不得不占首位时,返回 -1(首位不能为 0)


示例 1:

输入:21
输出:12
示例 2:

输入:531
输出:513
示例 3:

输入:135
输出:-1


欢迎大家一起答题!
最佳答案
2019-11-22 22:39:27
  1. def solve(num):
  2.     str1 = str(num)
  3.     i = len(str1)-1
  4.     if i < 1:
  5.         return -1
  6.     count = i - 1
  7.     while count >= 0:
  8.         if str1[count+1] >= str1[count]:
  9.             count -= 1
  10.         else:
  11.             list1 = list(str1[count:i+1])
  12.             list3 = list1.copy()
  13.             list3.sort()
  14.             x = []
  15.             x.append(list3[list3.index(list1[0])-1])
  16.             list3.remove(x[0])
  17.             for i in range(len(list3)-1,-1,-1):
  18.                 x.append(list3[i])
  19.             if count == 0:
  20.                 str2 = ''
  21.                 if x[0] == '0':
  22.                     return -1
  23.                 for each in x:
  24.                     str2 += each
  25.             else:
  26.                 str2 = str1[:count]
  27.                 for each in x:
  28.                     str2 += each
  29.             return int(str2)
  30.     return -1
复制代码

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-22 22:39:27 | 显示全部楼层    本楼为最佳答案   
  1. def solve(num):
  2.     str1 = str(num)
  3.     i = len(str1)-1
  4.     if i < 1:
  5.         return -1
  6.     count = i - 1
  7.     while count >= 0:
  8.         if str1[count+1] >= str1[count]:
  9.             count -= 1
  10.         else:
  11.             list1 = list(str1[count:i+1])
  12.             list3 = list1.copy()
  13.             list3.sort()
  14.             x = []
  15.             x.append(list3[list3.index(list1[0])-1])
  16.             list3.remove(x[0])
  17.             for i in range(len(list3)-1,-1,-1):
  18.                 x.append(list3[i])
  19.             if count == 0:
  20.                 str2 = ''
  21.                 if x[0] == '0':
  22.                     return -1
  23.                 for each in x:
  24.                     str2 += each
  25.             else:
  26.                 str2 = str1[:count]
  27.                 for each in x:
  28.                     str2 += each
  29.             return int(str2)
  30.     return -1
复制代码

评分

参与人数 1荣誉 +1 鱼币 +1 贡献 +1 收起 理由
zltzlt + 1 + 1 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-22 22:56:29 | 显示全部楼层
最后一位也不能为0吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-22 23:37:09 | 显示全部楼层
本帖最后由 Python3005 于 2019-11-23 01:12 编辑
  1. import itertools
  2. def fun(num):
  3.         for each in itertools.permutations((string := str(num)),len(string)):
  4.                 if (temp := int(''.join(each))) < num and len(str(temp)) == len(string):
  5.                         return temp
  6.         else:
  7.                 return -1
复制代码


加一句过滤一下应该能快不少:
  1. def fun(num):
  2.         if sorted(list(str(num))) == list(str(num)):
  3.                 return -1
  4.         else:
  5.                 for each in itertools.permutations((string := str(num)),len(string)):
  6.                         if (temp := int(''.join(each))) < num and len(str(temp)) == len(string):
  7.                                 return temp
  8.                 else:
  9.                         return -1
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-22 23:37:59 | 显示全部楼层
示例2 是返回 135 或者 351 或者 315 或者 513 都行吗?还是挑交换次数小的输出?交换是只能相邻的进行交换还是跳着也能交换?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-22 23:39:07 | 显示全部楼层
本帖最后由 peicd 于 2019-11-22 23:48 编辑

姑且认为是首位不是首尾,打错了,不然整句话有矛盾
  1. import itertools
  2. def abc(a):
  3.     for each in itertools.permutations(str(a),len(str(a))):
  4.         b=''.join(each)
  5.         if int(b)<a and  each[0]!='0':
  6.             return b
  7.     return -1
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-22 23:49:25 | 显示全部楼层
本帖最后由 凌九霄 于 2019-11-23 15:23 编辑
  1. def next_smaller(n: int):
  2.     s, t, z = list(str(n)), [], ''
  3.     try:
  4.         while 1:
  5.             t.append(s.pop())
  6.             if int(t[-1]) < int(s[-1]):
  7.                 z = s.pop()
  8.                 t.append(z)
  9.                 break
  10.         t = sorted(t)
  11.         z = [t.pop(t.index(z) - 1)]
  12.         r = int(''.join(s + z + t[::-1]))
  13.         if len(str(r)) == len(str(n)):
  14.             return r
  15.         else:
  16.             return -1
  17.     except IndexError:
  18.         return -1
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 00:01:20 | 显示全部楼层
peicd 发表于 2019-11-22 23:39
姑且认为是首位不是首尾,打错了,不然整句话有矛盾

排列组合当然是没有问题,但是,如果这个数字稍大一点,呵呵...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 00:09:53 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 00:21:36 | 显示全部楼层
阴阳神万物主 发表于 2019-11-22 23:37
示例2 是返回 135 或者 351 或者 315 或者 513 都行吗?还是挑交换次数小的输出?交换是只能相邻的进行交换 ...

我认为是返回比原数小的最大的那个数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 00:37:10 | 显示全部楼层
阴阳神万物主 发表于 2019-11-22 23:37
示例2 是返回 135 或者 351 或者 315 或者 513 都行吗?还是挑交换次数小的输出?交换是只能相邻的进行交换 ...

对数字进行位交换,找一个比他小的数返回
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 00:59:44 | 显示全部楼层
本帖最后由 peicd 于 2019-11-23 10:20 编辑

亲测,如果位数比较多,例如几百上万位,set后有微弱优势,如果位数比较少,例如123,不set有微弱优势
  1. def abc(num):
  2.     b=''
  3.     num = str(num)
  4.     num1=num
  5.     for i in range(len(num)):
  6.         Num = set(num)
  7.         a = min(Num)
  8.         if a=='0' and i==0:
  9.             Num.discard('0')
  10.             a=min(Num)
  11.         b+=a
  12.         num=num.replace(a,'',1)
  13.         if a<num1[i]:
  14.             return b+num
  15.     return -1
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 01:09:48 | 显示全部楼层

这样的话能快不少吧

  1. def fun(num):
  2.         if sorted(list(str(num))) == list(str(num)):
  3.                 return -1
  4.         else:
  5.                 for each in itertools.permutations((string := str(num)),len(string)):
  6.                         if (temp := int(''.join(each))) < num and len(str(temp)) == len(string):
  7.                                 return temp
  8.                 else:
  9.                         return -1
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-11-23 08:30:53 | 显示全部楼层
Unicorn# 发表于 2019-11-22 22:56
最后一位也不能为0吗

可以。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-11-23 08:32:43 | 显示全部楼层
阴阳神万物主 发表于 2019-11-22 23:37
示例2 是返回 135 或者 351 或者 315 或者 513 都行吗?还是挑交换次数小的输出?交换是只能相邻的进行交换 ...

返回 135、351、315、513 等等最小但离原数最大的那一个
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2019-11-23 08:37:10 | 显示全部楼层

解答错误

输入:135
输出:135
预期结果:-1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 08:43:09 | 显示全部楼层
本帖最后由 danteer 于 2019-11-23 14:50 编辑
  1. def func(num):
  2.     str1 = str(num)
  3.     if len(str1) < 2:
  4.         return -1
  5.     for i in range(0,len(str1)-1):
  6.         if str1[i] > str1[i+1]:
  7.             if i == 0 and str1[i+1] == '0':
  8.                 continue
  9.             if i+1 != len(str1) - 1:
  10.                 str2 = str1[:i] + str1[i+1] + str1[i] + str1[i+2:]
  11.             else:
  12.                 str2 = str1[:i] + str1[i+1] + str1[i]
  13.             return int(str2)
  14.     return -1
复制代码

以上是返回一个随机的更小的数
以下是返回一个最大的更小的数
  1. import itertools

  2. def solve(num):
  3.     str1 = str(num)
  4.     i = len(str1)-1
  5.     if i < 1:
  6.         return -1
  7.     count = i - 1
  8.     while count >= 0:
  9.         if str1[count+1] >= str1[count]:
  10.             count -= 1
  11.         else:
  12.             list1 = list(str1[count:i+1])
  13.             list3 = list1.copy()
  14.             list3.sort()
  15.             list2 = list(itertools.permutations(list3,len(list1)))
  16.             x = list2[list2.index(tuple(list1)) - 1]
  17.             if count == 0:
  18.                 str2 = ''
  19.                 if x[0] == '0':
  20.                     return -1
  21.                 for each in x:
  22.                     str2 += each
  23.             else:
  24.                 str2 = str1[:count]
  25.                 for each in x:
  26.                     str2 += each
  27.             return int(str2)
  28.     return -1
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 09:50:15 | 显示全部楼层
zltzlt 发表于 2019-11-23 08:37
解答错误

输入:135

重新改了一下。麻烦再试一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 12:42:09 | 显示全部楼层
本帖最后由 __mrsq__ 于 2019-11-23 12:45 编辑
  1. def fun279(num):
  2.     s = str(num)
  3.     n = len(s)
  4.     res = ''
  5.     if n==1:
  6.         return -1
  7.     for i in range(n-1,0,-1):
  8.         if s[i] < s[i-1]:
  9.             res = s[0:i-1]+s[i]+s[i-1]+s[i+1:]
  10.             if res[0]!= '0':
  11.                 return int(res)
  12.             
  13.     for i in res[2:]:
  14.         if i != '0':
  15.             if i >= res[1]:
  16.                 return -1
  17.             else:
  18.                 return int(i+s[1:s.index(i)]+s[0]+s[s.index(i)+1:])

  19.     return -1
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-11-23 13:15:35 | 显示全部楼层
我仔细看了半小时评论加例子才看清题意,佛了,意思说的不明不白的
题意是这样的?
第一,交换是任意交换,并且可以是多次交换
第二,最后输出的数字是所有比原数小的数字中的最大值
找不到这样相同位数的数字就-1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-25 23:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表