3216. 交换后字典序最小的字符串

问题描述:

        给你一个仅由数字组成的字符串 s,在最多交换一次 相邻 且具有相同 奇偶性 的数字后,返回可以得到的字典序最小的字符串。如果两个数字都是奇数或都是偶数,则它们具有相同的奇偶性。例如,5 和 9、2 和 4 奇偶性相同,而 6 和 9 奇偶性不同。

解题思路:

算法:
贪心法:从字符串的开头开始遍历,如果发现相邻的两个字符具有相同的奇偶性且前一个字符大于后一个字符,则交换这两个字符后返回结果。如果遍历完整个字符串都没有找到符合条件的交换,则返回原字符串。
时间复杂度和空间复杂度:
时间复杂度:由于只需要遍历字符串一次,因此时间复杂度为 O(n)。
空间复杂度:只需要常数级别的额外空间,因此空间复杂度为 O(1)。

参考代码:

class Solution {

public:

    string getSmallestString(string s) {

        const int n = s.size();

        for (int i = 0; i < n - 1; i++) {

            if (!((s[i] ^ s[i + 1]) & 1) && s[i + 1] < s[i]) {

                swap(s[i], s[i + 1]);

                break;

            }

        }

        return s;

    }

};

虽然给定材料未直接提及查找比当前字符串字典序大的最小字符串的方法,但可以结合字典序相关知识进行分析。 字典序是指在字典中单词排列的顺序,对于两个长度相同的字符串,在出现不同的第一个位置上,字符在字母表中出现早的字符串字典序更小;若长度不同,较短字符串在相同位置字母与较长字符串相同,则较短字符串字典序更小 [^3]。 查找比当前字符串字典序大的最小字符串的一种思路如下: 1.字符串的末尾开始向前遍历,找到第一个满足 `str[i] < str[i + 1]` 的位置 `i`。这意味着从 `i+1` 到字符串末尾是一个降序序列,无法通过调整这部分得到比当前字符串字典序大的字符串,而 `i` 位置是可以进行调整的起始点。 2. 如果找到了这样的位置 `i`,再从字符串末尾开始向前遍历,找到第一个大于 `str[i]` 的字符 `str[j]`。 3. 交换 `str[i]` 和 `str[j]`。 4. 最后将从 `i + 1` 到字符串末尾的字符反转,因为这部分原本是降序的,反转后变为升序,能保证得到的字符串是比原字符串字典序大的最小字符串。 以下是实现该算法的 Python 代码示例: ```python def next_permutation(s): s = list(s) n = len(s) i = n - 2 # 找到第一个满足 s[i] < s[i + 1] 的位置 i while i >= 0 and s[i] >= s[i + 1]: i -= 1 if i >= 0: j = n - 1 # 找到第一个大于 s[i] 的字符 s[j] while j > i and s[j] <= s[i]: j -= 1 # 交换 s[i] 和 s[j] s[i], s[j] = s[j], s[i] # 反转从 i + 1 到字符串末尾的字符 s[i + 1:] = reversed(s[i + 1:]) return ''.join(s) # 示例 current_string = "abc" result = next_permutation(current_string) print(result) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值