Arrays 查找对给定数组排序所需的删除然后追加操作数
这是一个面试问题。Arrays 查找对给定数组排序所需的删除然后追加操作数,arrays,algorithm,sorting,language-agnostic,Arrays,Algorithm,Sorting,Language Agnostic,这是一个面试问题。swap意味着从数组中删除任何元素并将其附加到同一数组的后面。给定一个整数数组,找到对数组排序所需的最小交换数swap 有比O(n^2)更好的解决方案吗 例如: 输入数组:[3124] 交换的数量:2([3124]->[1243]->[1234])。观察:如果一个元素被交换到后面,它以前的位置并不重要。无需多次交换任何元素 观察:最后一次交换(如果有)必须移动最大的元素 观察:在交换之前,必须对数组(不包括最后一个元素)进行排序(按以前的交换或最初的交换) 排序算法,假设值是连
swap
意味着从数组中删除任何元素并将其附加到同一数组的后面。给定一个整数数组,找到对数组排序所需的最小交换数swap
有比O(n^2)
更好的解决方案吗
例如:
输入数组:[3124]
交换的数量
:2([3124]->[1243]->[1234])。观察:如果一个元素被交换到后面,它以前的位置并不重要。无需多次交换任何元素
观察:最后一次交换(如果有)必须移动最大的元素
观察:在交换之前,必须对数组(不包括最后一个元素)进行排序(按以前的交换或最初的交换)
排序算法,假设值是连续的:从1开始查找连续(按值)元素的最长排序子序列:
31524
依次交换所有较高的元素:
1 5 2 4 3
1 5 2 3 4
123445
要查找O(n)中的交换数,请查找从1开始的连续元素的最长排序子序列的长度:
- 期望值=1
- 对于顺序中的每个元素
- 如果元素==预期值
- 预期+=1
- 如果元素==预期值
- 预期收益-1
- 互换=0
- 环路
- 查找最大元素的第一个实例,并检测数组是否已排序
- 如果数组已排序,则返回交换
- 否则,从数组中删除找到的元素并进行增量交换
- 将每个元素包装在{oldPos,newPos,value}中
- 制作阵列的浅层副本
- 按值对数组排序
- 存储每个元素的新位置
- 在(未排序)副本中的newPos'上运行置换算法
O(nlogn)
中起作用,即使我们不采用连续值的数组。如果我们这样做-它可以在
O(n)
中完成。
一种方法是使用O(n)
space和O(nlogn)
time
给定数组A
将其(O(nlogn)
)排序到第二个数组B
现在。。。(数组从1索引)
问题归结为查找排序数组的最长前缀,该前缀在输入数组中显示为子序列。这将确定不需要排序的元素。其余的元素需要从最小到最大逐个删除,并追加到后面 在您的示例中,
[3,1,2,4]
,已经排序的子序列是[1,2]
。最佳解决方案是删除剩余的两个元素,3
和4
,并将它们附加在后面。因此,最佳解决方案是两次“交换”
可以使用O(n)
额外内存在O(n)
时间内查找子序列。下面的伪代码将实现这一点(代码恰好也是有效的Python):
如您的示例所示,如果数组包含从1
到n
的整数排列,则可以使用O(1)
内存在O(n)
时间内解决问题:
l = [1, 2, 3, 5, 4, 6]
s = 1
for item in l:
if item == s:
s += 1
print len(l) - s + 1
更一般地说,只要我们事先知道输出数组,就可以使用第二种方法,因此不需要通过排序找到它。这可以在O(n log n)中完成
首先找到数组中的最小元素。现在,查找在该元素之前出现的max元素。称之为最大左。必须为数组的min元素之前的所有元素调用swap()
现在,在min元素的右侧找到最长的递增子序列,以及应该跳过值大于max_left的元素的约束。
所需的交换数量为大小(数组)-大小(LIS)
例如考虑数组,
7891251118
数组中的最小元素为1。所以我们在最小元素之前找到最大值
7 8 9 | 1 2 5 11 18
最大左=9
现在,找到min右边元素小于9的LIS
LIS=1,2,5
互换数量=8-3=5
如果max元素为null,即min是第一个元素,则查找数组的LIS,所需答案为size(数组)-size(LIS)
比如说
25443
max_left为空。LIS是23
无掉期=大小(数组)-大小(LIS)=4~2=2
< P> <强> @所有,由ITayKao和@ NPE提供的可接受解是完全错误的< /强>,因为它不考虑交换元素的未来排序… 对于许多测试用例,如: 3 1 2 5 4 正确输出:4 但它们的代码输出为3 说明:3 1 2 5 4--->1 2 5 4 3--->1 2 4 3 5--->1 2 3 5 4--->1 2 3 4 5 PS:我不能在那里发表评论,因为声誉很低int numSwaps(int arr[],int length){
int numSwaps(int arr[], int length) {
bool sorted = false;
int swaps = 0;
while(!sorted) {
int inversions = 0;
int t1pos,t2pos,t3pos,t4pos = 0;
for (int i = 1;i < length; ++i)
{
if(arr[i] < arr[i-1]){
if(inversions){
tie(t3pos,t4pos) = make_tuple(i-1, i);
}
else tie(t1pos, t2pos) = make_tuple(i-1, i);
inversions++;
}
if(inversions == 2)
break;
}
if(!inversions){
sorted = true;
}
else if(inversions == 1) {
swaps++;
int temp = arr[t2pos];
arr[t2pos] = arr[t1pos];
arr[t1pos] = temp;
}
else{
swaps++;
if(arr[t4pos] < arr[t2pos]){
int temp = arr[t1pos];
arr[t1pos] = arr[t4pos];
arr[t4pos] = temp;
}
else{
int temp = arr[t2pos];
arr[t2pos] = arr[t1pos];
arr[t1pos] = temp;
}
}
}
return swaps;
}
bool=false;
int-swaps=0;
而(!排序){
整数倒数=0;
int t1pos、t2pos、t3pos、t4pos=0;
对于(int i=1;il = [1, 2, 3, 5, 4, 6]
s = 1
for item in l:
if item == s:
s += 1
print len(l) - s + 1
int numSwaps(int arr[], int length) {
bool sorted = false;
int swaps = 0;
while(!sorted) {
int inversions = 0;
int t1pos,t2pos,t3pos,t4pos = 0;
for (int i = 1;i < length; ++i)
{
if(arr[i] < arr[i-1]){
if(inversions){
tie(t3pos,t4pos) = make_tuple(i-1, i);
}
else tie(t1pos, t2pos) = make_tuple(i-1, i);
inversions++;
}
if(inversions == 2)
break;
}
if(!inversions){
sorted = true;
}
else if(inversions == 1) {
swaps++;
int temp = arr[t2pos];
arr[t2pos] = arr[t1pos];
arr[t1pos] = temp;
}
else{
swaps++;
if(arr[t4pos] < arr[t2pos]){
int temp = arr[t1pos];
arr[t1pos] = arr[t4pos];
arr[t4pos] = temp;
}
else{
int temp = arr[t2pos];
arr[t2pos] = arr[t1pos];
arr[t1pos] = temp;
}
}
}
return swaps;
}
function findSwaps(){
let arr = [4, 3, 1, 2];
let swap = 0
var n = arr.length
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
if (arr[i] > arr[j]) {
arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j]
swap = swap + 1
}
}
}
console.log(arr);
console.log(swap)
}
public class MinimumSwaps2
{
public static void minimumSwapsMain(int[] arr)
{
Dictionary<int, int> dic = new Dictionary<int, int>();
Dictionary<int, int> reverseDIc = new Dictionary<int, int>();
int temp = 0;
int indx = 0;
//find the maximum number from the array
int maxno = FindMaxNo(arr);
if (maxno == arr.Length)
{
for (int i = 1; i <= arr.Length; i++)
{
dic[i] = arr[indx];
reverseDIc.Add(arr[indx], i);
indx++;
}
}
else
{
for (int i = 1; i <= arr.Length; i++)
{
if (arr.Contains(i))
{
dic[i] = arr[indx];
reverseDIc.Add(arr[indx], i);
indx++;
}
}
}
int counter = FindMinSwaps(dic, reverseDIc, maxno);
}
static int FindMaxNo(int[] arr)
{
int maxNO = 0;
for (int i = 0; i < arr.Length; i++)
{
if (maxNO < arr[i])
{
maxNO = arr[i];
}
}
return maxNO;
}
static int FindMinSwaps(Dictionary<int, int> dic, Dictionary<int, int> reverseDIc, int maxno)
{
int counter = 0;
int temp = 0;
for (int i = 1; i <= maxno; i++)
{
if (dic.ContainsKey(i))
{
if (dic[i] != i)
{
counter++;
var myKey1 = reverseDIc[i];
temp = dic[i];
dic[i] = dic[myKey1];
dic[myKey1] = temp;
reverseDIc[temp] = reverseDIc[i];
reverseDIc[i] = i;
}
}
}
return counter;
}
}
def find_cycles(array):
cycles = []
remaining = set(array)
while remaining:
j = i = remaining.pop()
cycle = [i]
while True:
j = array[j]
if j == i:
break
array.append(j)
remaining.remove(j)
cycles.append(cycle)
return cycles
def minimum_swaps(seq):
return sum(len(cycle) - 1 for cycle in find_cycles(seq))
for(int count = 1; count<=length; count++)
{
tempSwap=0; //it will count swaps per iteration
for(int i=0; i<length-1; i++)
if(a[i]>a[i+1])
{
swap(a[i],a[i+1]);
tempSwap++;
}
if(tempSwap!=0) //check if array is already sorted!
swap += tempSwap;
else
break;
}
System.out.println(swaps);
static int minimumSwaps(int[] arr) {
int swap=0;
boolean visited[]=new boolean[arr.length];
for(int i=0;i<arr.length;i++){
int j=i,cycle=0;
while(!visited[j]){
visited[j]=true;
j=arr[j]-1;
cycle++;
}
if(cycle!=0)
swap+=cycle-1;
}
return swap;
}
}
int temp = 0, swaps = 0;
for (int i = 0; i < arr.length;) {
if (arr[i] != i + 1){
// System.out.println("Swapping --"+arr[arr[i] - 1] +" AND -- "+arr[i]);
temp = arr[arr[i] - 1];
arr[arr[i] - 1] = arr[i];
arr[i] = temp;
++swaps;
} else
++i;
// System.out.println("value at position -- "+ i +" is set to -- "+ arr[i]);
}
return swaps;
def minimumSwaps(arr):
swaps = 0
'''
first sort the given array to determine the correct indexes
of its elements
'''
temp = sorted(arr)
# compare unsorted array with the sorted one
for i in range(len(arr)):
'''
if ith element in the given array is not at the correct index
then swap it with the correct index, since we know the correct
index because of sorting.
'''
if arr[i] != temp[i]:
swaps += 1
a = arr[i]
arr[arr.index(temp[i])] = a
arr[i] = temp[i]
return swaps
int minimumSwaps(int[] a) {
int swaps = 0;
int i = 0;
while(i < a.length) {
int position = a[i] - 1;
if(position != i) {
int temp = a[position];
a[position] = a[i];
a[i] = temp;
swaps++;
} else {
i++;
}
}
return swaps;
}
static int minMoves(int arr[], int n) {
if (arr.length == 0) return 0;
boolean[] willBeMoved = new boolean[n]; // keep track of elements to be removed and appended
int min = arr[n - 1]; // keep track of the minimum
for (int i = n - 1; i >= 0; i--) { // traverse the array from the right
if (arr[i] < min) min = arr[i]; // found a new min
else if (arr[i] > min) { // arr[i] has a smaller element to the right, so it will need to be moved at some point
willBeMoved[i] = true;
}
}
int minToBeMoved = -1; // keep track of the minimum element to be removed and appended
int result = 0; // the answer
for (int i = 0; i < n; i++) { // traverse the array from the left
if (minToBeMoved == -1 && !willBeMoved[i]) continue; // find the first element to be moved
if (minToBeMoved == -1) minToBeMoved = i;
if (arr[i] > arr[minToBeMoved]) { // because a smaller value will be moved to the end, arr[i] will also have to be moved at some point
willBeMoved[i] = true;
} else if (arr[i] < arr[minToBeMoved] && willBeMoved[i]) { // keep track of the min value to be moved
minToBeMoved = i;
}
if (willBeMoved[i]) result++; // increment
}
return result;
}