给定一个数字字符串str ,任务是找到可以通过交换不同奇偶校验的相邻数字形成的最小整数。
例子:
Input: 836360
Output: 338660
Explanation:
1st Swap: 836360 -> 386360
2nd Swap: 386360 -> 383660
3rd Swap: 383660 -> 338660
Input: 1003
Output: 13
方法:
我们可以观察到,在重复的交换中,我们可以将str的偶数和奇数拆分为两个单独的块。各自块中的数字顺序将与它们在字符串的出现顺序相同,因为不允许在一个块内交换(相同奇偶校验)。因此,在将str分为两个单独的块之后,我们需要遍历这两个块并将当前指向的两个值中的最小值附加到答案中。此操作后生成的最后一个字符串,然后删除前导0(如果有),是必需的答案。
例子:
在836360中,偶数和奇数块的出现顺序分别为{8,6,6,0}和{3,3}。
因此,形成的最小数ans如下:
- ans = ans + min(8,3)=> ans = 3
- ans = ans + min(8,3)=> ans = 33
- 由于所有的奇数位都已用尽,因此需要将其余的偶数位一一相加。
- 因此,所需的答案是338660
下面是上述方法的实现:
C++
// C++ Program to find the
// smallest number possible
// by swapping adjacent digits
// of different parity
#include
using namespace std;
// Function to return the
// smallest number possible
string findAns(string s)
{
int digit;
// Arrays to store odd and
// even digits in the order
// of their appearance in
// the given string
vector odd;
vector even;
// Insert the odd and
// even digits
for (auto c : s) {
digit = c - '0';
if (digit & 1)
odd.push_back(digit);
else
even.push_back(digit);
}
// pointer to odd digit
int i = 0;
// pointer to even digit
int j = 0;
string ans = "";
while (i < odd.size()
and j < even.size()) {
if (odd[i] < even[j])
ans += (char)(odd[i++] + '0');
else
ans += (char)(even[j++] + '0');
}
// In case number of even and
// odd digits are not equal
// If odd digits are remaining
while (i < odd.size())
ans += (char)(odd[i++] + '0');
// If even digits are remaining
while (j < even.size())
ans += (char)(even[j++] + '0');
// Removal of leading 0's
while (ans[0] == '0') {
ans.erase(ans.begin());
}
return ans;
}
int main()
{
string s = "894687536";
cout << findAns(s);
return 0;
}
Java
// Java program to find the smallest
// number possible by swapping adjacent
// digits of different parity
import java.util.*;
class GFG{
// Function to return the
// smallest number possible
static String findAns(String s)
{
int digit;
// Arrays to store odd and even
// digits in the order their
// appearance in the given String
Vector odd =new Vector();
Vector even = new Vector();
// Insert the odd and
// even digits
for(char c : s.toCharArray())
{
digit = c - '0';
if (digit % 2 == 1)
odd.add(digit);
else
even.add(digit);
}
// Pointer to odd digit
int i = 0;
// Pointer to even digit
int j = 0;
String ans = "";
while (i < odd.size() && j < even.size())
{
if (odd.get(i) < even.get(j))
ans += (char)(odd.get(i++) + '0');
else
ans += (char)(even.get(j++) + '0');
}
// In case number of even and
// odd digits are not equal
// If odd digits are remaining
while (i < odd.size())
ans += (char)(odd.get(i++) + '0');
// If even digits are remaining
while (j < even.size())
ans += (char)(even.get(j++) + '0');
// Removal of leading 0's
while (ans.charAt(0) == '0')
{
ans = ans.substring(1);
}
return ans;
}
// Driver code
public static void main(String[] args)
{
String s = "894687536";
System.out.print(findAns(s));
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 Program to find the
# smallest number possible
# by swapping adjacent digits
# of different parity
# Function to return the
# smallest number possible
def findAns(s):
# Arrays to store odd and
# even digits in the order
# of their appearance in
# the given string
odd = []
even = []
# Insert the odd and
# even digits
for c in s:
digit = int(c)
if (digit & 1):
odd.append(digit)
else:
even.append(digit)
# pointer to odd digit
i = 0
# pointer to even digit
j = 0
ans = ""
while (i < len(odd) and j < len(even)):
if (odd[i] < even[j]):
ans += str(odd[i])
i = i + 1
else:
ans += str(even[j])
j = j + 1
# In case number of even and
# odd digits are not equal
# If odd digits are remaining
while (i < len(odd)):
ans += str(odd[i])
i = i + 1
# If even digits are remaining
while (j < len(even)):
ans += str(even[j])
j = j + 1
# Removal of leading 0's
while (ans[0] == '0'):
ans = ans[1:]
return ans
# Driver Code
s = "894687536"
print(findAns(s))
# This code is contributed by yatin
C#
// C# program to find the smallest
// number possible by swapping adjacent
// digits of different parity
using System;
using System.Collections.Generic;
class GFG{
// Function to return the
// smallest number possible
static String findAns(String s)
{
int digit;
// Arrays to store odd and even
// digits in the order their
// appearance in the given String
List odd = new List();
List even = new List();
// Insert the odd and
// even digits
foreach(char c in s.ToCharArray())
{
digit = c - '0';
if (digit % 2 == 1)
odd.Add(digit);
else
even.Add(digit);
}
// Pointer to odd digit
int i = 0;
// Pointer to even digit
int j = 0;
String ans = "";
while (i < odd.Count && j < even.Count)
{
if (odd[i] < even[j])
ans += (char)(odd[i++] + '0');
else
ans += (char)(even[j++] + '0');
}
// In case number of even and
// odd digits are not equal
// If odd digits are remaining
while (i < odd.Count)
ans += (char)(odd[i++] + '0');
// If even digits are remaining
while (j < even.Count)
ans += (char)(even[j++] + '0');
// Removal of leading 0's
while (ans[0] == '0')
{
ans = ans.Substring(1);
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
String s = "894687536";
Console.Write(findAns(s));
}
}
// This code is contributed by 29AjayKumar
输出:
846869753
时间复杂度: O(N) ,其中N是给定字符串的大小。