由于题目中说了最多只能交换一次,也就是可以不交换或者交换一次,从贪心的角度,那么一定选择字符串中最小的那一个字符作为整个字符串靠前的字符更优,如果出现多个相同的最小字符,那么显然应该选择最靠近字符串末尾的那一个。证明如下:
假设一个字符串,最小的字符用∗表示,非最小的字符用@表示,假设一个字符串可以写成如下形式:@@∗@@∗,那么可以枚举交换策略,如下:
源串: @@∗@@∗
策略一:∗@@@@∗
策略二:∗@@∗@@
可以看到,第二种策略一定优于第一种策略,因为相同位置上,将更加靠后的最小字符交换靠前的字符会更优。
const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
let s = '';
rl.on('line', (line) => {
  s = line;
  const t = [...s].sort();
  for (let i = 0; i < s.length; i++) {
    if (s[i] !== t[i]) {
      for (let j = s.length - 1; j >= 0; j--) {
        if (s[j] === t[i]) {
          s = s.substring(0, i) + s[j] + s.substring(i + 1, j) + s[i] + s.substring(j + 1);
          break;
        }
      }
      break;
    }
  }
  console.log(s);
  rl.close();
});
s = input()
t = sorted(s)
for i in range(len(s)):
    if s[i] != t[i]:
        for j in range(len(s) - 1, -1, -1):
            if s[j] == t[i]:
                s = s[:i] + s[j] + s[i+1:j] + s[i] + s[j+1:]
                break
        break
print(s)
import java.util.Arrays;
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        char[] charArray = s.toCharArray();
        char[] sortedArray = Arrays.copyOf(charArray, charArray.length);
        Arrays.sort(sortedArray);
        for (int i = 0; i < charArray.length; i++) {
            if (charArray[i] != sortedArray[i]) {
                for (int j = charArray.length - 1; j >= 0; j--) {
                    if (charArray[j] == sortedArray[i]) {
                        char temp = charArray[i];
                        charArray[i] = charArray[j];
                        charArray[j] = temp;
                        break;
                    }
                }
                break;
            }
        }
        System.out.println(new String(charArray));
    }
}
#include <bits/stdc++.h>
using namespace std;
int main(void) {
    string s;
    cin >> s;
    string t(s);
    sort(t.begin(), t.end());
    for (int i = 0; i < s.size(); i++) {
        if (s[i] != t[i]) {
            for (int j = s.size() - 1; j >= 0; j--) {
                if (s[j] == t[i]) {
                    swap(s[i], s[j]);
                    break;
                }
            }
            break;
        }
    }
    cout << s << endl;
}
        给定一个字符串 s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。
变换规则:交换字符串中任意两个不同位置的字符。
一串小写字母组成的字符串 s。s是都是由小写字符组成, 1≤s.length≤1000
按照要求进行变换得到的最小字符串
输入
abcdef
输出
abcdef
说明:abcdef 已经是最小字符串,不需要交换
输入
bcdefa
输出
acdefb
说明: a 和 b 进行位置交换,可以等到最小字符串