我正在寻找一种方法来将2D数组中的所有元素向上和向上移位,以便满足特定条件的元素留在数组的末尾。我的意思的简化示例:
一个二维整数数组,用1填充,四个零。
1 1 1 1 1
1 1 1 1 0
1 1 1 0 1
1 1 1 1 1
0 0 1 1 1
我想要做的是通过移动其他元素来填充孔(零),在末尾留下零。期望的结果是:
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 0 0 0 0
在我的项目中,我正在处理2D对象数组,其状态是决定移位的因素。我只是在寻找能够实现这一结果的基本算法。有一个简单的方法吗?
答案 0 :(得分:2)
迭代数组并计算零。每次你发现零加1到你的计数器并将零替换为1.然后从数组的末尾开始到它的开头,用N替换0,其中N是零的总数。
答案 1 :(得分:0)
对第一个数组中的每个数组进行冒泡排序,并按照您的顺序对它们进行排序
for (i=0; i<array1.length; i++){
yourBubblesort(array1[i]);
}
实施冒泡排序非常简单,你必须在你的家庭作业中做点什么
答案 2 :(得分:0)
尝试这种方法
public void shiftZeros(int[] arr )
{
int count;
for(int j=0;j<arr.length-1;j++)
{
if(arr[j]=0)
{
arr[j]=1;
count++;
}
}
for(int j=arr.length-1,i=1;i<count;i++,j--)
{
arr[j]=0;
}
}
答案 3 :(得分:0)
这是一种使用复制到新数组的方法
当元素即将满足处理结束时,将不会重叠。
修改强>
仅为了完整性,这里是上面算法的实现
private E[][] shift(E[][] input) {
int maxLen = get2DMaxLen(input);
int i_next = 0, j_next = 0;
int i_least = input.length-1, j_least = maxLen-1;
E[][] actual = new E[input.length][maxLen];
for(int i = 0; i < input.length; i++) {
for(int j = 0; j < input[i].length; j++) {
if(meetsCondition(input[i][j])) {
actual[i_least][j_least--] = input[i][j];
if(j_least == -1) {
j_least = maxLen-1;
i_least--;
}
} else {
actual[i_next][j_next++] = input[i][j];
if(j_next == input[i].length) {
j_next = 0;
i_next++;
}
}
}
}
return actual;
}
测试输入
0 1 1 0 1
0 1 1 1 0
1 0 1 0 1
1 1 0 1 1
0 0 1 1 1
输出
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 0 0 0 0
0 0 0 0 0
答案 4 :(得分:0)
效率低下的版本:
在商店中迭代所有非0项(例如queue,可以使用LinkedList进行模拟)。
再次迭代,只需将存储的项目逐个拉入数组
迭代器通过类似的东西:
for (int i = 0; i < arr.length; i++)
for (int j = 0; j < arr[i].length; j++)
...
更多(空间)效率版本:
同时迭代数组两次,读取每个值并将它们放在正确的位置。
伪代码:(希望足够可读)
while ahead.hasNext
// skip all 0s
do
i = ahead.next
while i == 0
behind.writeNext(i)
// the rest must all be 0
while behind.hasNext
behind.writeNext(0)
我不能给你代码,因为我不能为你做所有的工作。
答案 5 :(得分:0)
为什么不对列进行排序,然后对每行进行排序?有很多算法可以做到这一点。
答案 6 :(得分:0)
对于上面的确切问题,解决方案可以是:
从两个指针开始,一个位于数组的左上角,另一个位于右下角。让我们分别调用这些第一和第二指针。现在使用第一个指针行方式遍历数组。当你找到一个要放到末尾的元素时(在这种情况下为'0'),检查第二个元素指向的元素。如果第二个元素是0,则递减第二个指针指向2-d数组中的倒数第二个元素。现在检查这个元素,如果这也是'0'再次递减第二个指针,依此类推,直到你达到'1'(一个必须在数组开头的元素)。然后交换这两个元素。在指针相互交叉的任何时间点,阵列都按要求排序。
以下java代码将执行此操作: 最初变量endi和endj指向最后一个元素(第二个指针),变量i和j指向第一个元素(第一个指针)。数组大小为m X n。
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
if(a[i][j]==0)
{
while(a[endi][endj]!=1 && i*m+j<endi*m+endj) //second part of the condition checks if i,j and endi,endj haven't crossed over
{
endj--;
if(endj==-1)
{
endj=n-1;
endi--;
if(endi==-1)
{
disparr(a,m,n);
System.exit(0);
}
}
}
if(!(i*m+j<endi*m+endj))//if the pointer have crossed over
{
disparr(a,m,n);
System.exit(0);
}
int t=a[i][j];
a[i][j]=a[endi][endj];
a[endi][endj]=t;
}
}
}
对于例如上述代码的其他改进是可能的。删除用于递减函数指针并调用它的代码。但代码可以正常工作。