php-面试题,用最少的迭代,使数组所有元素变换为平均值(平衡)

问题描述

面试题,用最少的迭代,使数组所有元素变换为平均值(平衡)

输入:数组,所有值为非负整数
目标:通过变换使数组的每个值为所有值的平均值,并且迭代次数最少
变换方法:某个值自身减一,使其紧邻左边或紧邻右边的值加一。数组第一个值只能向右传递1,最后一个向左传递1. 变换过程中数组内所有值不可为负。
例1:
输入 : [0, 3, 3]
第一次: [1, 2, 3] [1, 3, 2]
第二次: [2, 2, 2]
例2
[2, 4, 6, 2, 1]
[3, 3, 5, 2, 2]
[3, 3, 4, 2, 3]
[3, 3, 3, 3, 3]
例3
[1, 0, 7, 0]
[1, 1, 6, 0]
[2, 1, 5, 0]
[2, 2, 4, 0]
[2, 2, 3, 1]
[2, 2, 2, 2]
这个问题有什么好的算法解决吗,例子不是唯一解。求思路,用php实现。

解决方案

$ar = [0, 3, 3];
$ar = [2, 4, 6, 2, 1];
$ar = [1, 0, 7, 0];
$ar = [5, 5, 5, 5, 25];

do {
  $loop = 0;
  for($i=0; $i<count($ar) - 1; $i++) {
    if($n = casecmp($ar[$i], $ar[$i+1])) {
      $ar[$i] += $n;
      $ar[$i+1] -= $n;
      $loop++;
    }
  }
  printf("[%s]n", join(', ', $ar));
}while($loop);

function casecmp($a, $b) {
  if($a == $b) return 0;
  return $a > $b ? -1 : 1;
}

解决方案二:

[1, 1, 6, 0]
[2, 1, 5, 0]
这是怎么来的,某个值自身减一,使其左边或右边的值加一,6减少1怎么加到第一个去的?

解决方案三:

<?php
function printArray($array){
    print "[";
    foreach ($array as $key => $value)
        $key==count($array)-1? print $value :print $value.", ";
    print "]n";
}
function balance($a,$averge){
    while (1){
        $count=0;
    foreach ($a as $key => $value){
        $key==0?$left=null:$left=$a[$key-1];
        $key==count($a)-1?$right=null:$right=$a[$key+1];
        $value=$a[$key];
        if (is_null($left)&&$value>$averge) { $a[$key]--; $a[$key+1]++; continue;}
        if (is_null($right)&&$value>$averge) { $a[$key]--; $a[$key-1]++; continue;}
        if (!is_null($left)&&!is_null($right)&&$left<$averge&&$value!=0) { $a[$key]--; $a[$key-1]++;continue;}
        if (!is_null($left)&&!is_null($right)&&$right<$averge&&$value!=0) { $a[$key]--; $a[$key+1]++;continue;}
        $count++;
        if($count==count($a)) return 0;
    }
    printArray($a);
    }
}

if($argc<2) exit("php solution.php number1 number2 number3 ...n");
array_shift($argv);
foreach ($argv as $number){
    if(!preg_match("/^[1-9]d*$|^0$/",$number))
        exit("wrong number: $numbern");
}
$averge=array_sum($argv)/($argc-1);
if(!is_int($averge)) exit("numbers you input,can not be balancen");
printArray($argv);
balance($argv,$averge);
?>

解决方案四:

我用了模仿例子的方法,无论自身大小,只要左右两边的值小于平均值就传递,显而易见的是有许多重复传递,谁还有其他方法吗,多谢
[5, 5, 5, 5, 25]
[6, 5, 5, 5, 24] //除了第一个值,所有值都向左传递了1
[7, 5, 5, 5, 23]
[8, 5, 5, 5, 22]
[9, 5, 5, 5, 21]// [9, 5, 5, 5, 21] [9, 4, 6, 5, 21] [9, 5, 5, 5, 21] [9, 5, 6, 4, 21] [9, 5, 6, 5, 20] 冗余
[9, 5, 6, 5, 20]
[9, 5, 7, 5, 19]
[9, 5, 8, 5, 18]
[9, 5, 9, 5, 17]
[9, 6, 9, 5, 16]
[9, 7, 9, 5, 15]
[9, 8, 9, 5, 14]
[9, 9, 9, 5, 13]
[9, 9, 9, 6, 12]
[9, 9, 9, 7, 11]
[9, 9, 9, 8, 10]
[9, 9, 9, 9, 9]

解决方案五:

如果从更广范围论,之上概念让人雾蒙蒙的,比如说一个较大的数字向左右如果跨多个位置如何得知?是否要循环检测其位置?如果要循环得到那么真的会比现有函数更高效?现有求数组平均值函数及数组生成重复值函数难道效率不行?

解决方案六:

减少迭代其实有些自欺欺人,比如用很多判断语句执行,其实处理器还是要操作,并不比直接迭代更高效?
比如循环一遍数组求得其均值再一遍赋值,这样语句精简适用更广

解决方案七:

求出均值,然后从数组首尾两段比较可以嘛?

时间: 2024-09-19 23:52:53

php-面试题,用最少的迭代,使数组所有元素变换为平均值(平衡)的相关文章

《Python Cookbook(第3版)中文版》——1.2 从任意长度的可迭代对象中分解元素

1.2 从任意长度的可迭代对象中分解元素 1.2.1 问题 需要从某个可迭代对象中分解出N个元素,但是这个可迭代对象的长度可能超过N,这会导致出现"分解的值过多(too many values to unpack)"的异常. 1.2.2 解决方案 Python的"表达式"可以用来解决这个问题.例如,假设开设了一门课程,并决定在期末的作业成绩中去掉第一个和最后一个,只对中间剩下的成绩做平均分统计.如果只有4个成绩,也许可以简单地将4个都分解出来,但是如果有24个呢?表

怎样用C语言编写一个迷宫游戏,能否再进一步使迷宫可以自主变换

问题描述 怎样用C语言编写一个迷宫游戏,能否再进一步使迷宫可以自主变换 就是用c语言实现一个迷宫游戏,如果可以的话能否在加一个条件就是:比如每走10步迷宫就会发生一定的变化,当然一定要能走出去,如果走不出去也就没意义了 解决方案 动态变化的话,想象是蛮复杂的,得用点动态规划什么的算法吧,没有涉及过,期待大神

link中如何迭代一个数组,用户可以暂停,然后恢复,继续输出?

问题描述 link中如何迭代一个数组,用户可以暂停,然后恢复,继续输出? link中如何迭代一个数组,用户可以暂停,然后恢复,继续输出? 解决方案 定时器,每次让索引+1,返回数据 按钮控制timer1.Stop() Start()

《D3.js数据可视化实战手册》——2.4 迭代选集中的元素

2.4 迭代选集中的元素 有些时候,我们需要遍历选集中的所有元素,再根据它们的不同位置分别进行不同的处理.本节将使用D3的选集迭代API来实现. 2.4.1 准备阶段 请在浏览器中打开如下文件的本地副本. https://github.com/NickQiZhu/d3-cookbook/blob/master/src/chapter2/selection-iteration.html 2.4.2 开始编程 D3为其选集对象提供了简单的迭代接口,我们可以用类似JavaScript数组的方式迭代D3

[程序员面试题精选100题]10.排序数组中和为给定值的两个数字

剑指Offer之和为S的两个数字 剑指Offer之和为S的连续正数序列 扩展(1):输入一个数组,判断这个数组中是不是存在三个数字i, j, k,满足i+j+k等于0. 扩展(2):如果输入的数组是没有排序的,但知道里面数字的范围,其他条件不变,如何在O(n)时间里找到这两个数字?这个的基本思路是先用哈希表实现O(n)的排序(请参照本面试题系列的第57题),接下来的步骤都一样了.

温度变化可使改变汽车颜色变换的热敏涂料诞生

据英国http://www.aliyun.com/zixun/aggregation/39351.html">每日邮报报道,目前,英国专家最新视频显示,使用一种热敏反应涂料涂在尼桑Skyline R33汽车表面,当倾倒冷水时会使汽车变成橙色. 无论什么时候将水倾倒在汽车上,车身都将变色,这种涂料被称为"热彩色涂料",意味着当温度变化时,车身颜色将从一种颜色变成另一种颜色.当温度升高时,涂料将变成无色. 反应元素能够悬浮在油漆中的水或者溶剂,必须使用这一原理将微粒散布在整

前端面试题:高效地随机选取数组中的元素

有前端题目大概是这样的:考虑到性能问题,如何快速从一个巨大的数组中随机获取部分元素. 比如有个数组有100K个元素,从中不重复随机选取10K个元素. 为了演示方便我们将数据简化,先给出方案最后再用大点的数据来测试性能的对比. 常规解法 常规做法倒也不难,生成一个0到数组长度减1的随机数,这个数也就是被选中元素在原数组中的下标,获得该元素后将值保存到另一个数组同时通过数组的splice方法将该元素从原数组中删除,以保证下次不会重复取到. 按以上思路,代码大概就是这样的: //元素总数,为了方便演示

禁止&amp;amp;lt;a&amp;amp;gt;元素-如何让&amp;amp;lt;a&amp;amp;gt;元素禁止,不能点击

问题描述 如何让<a>元素禁止,不能点击 如何让jsp中元素处于禁止状态,不能点击,等做完其他判断后解禁 解决方案 这个貌似不行吧!标签不就是超链接标签么? 解决方案二: 解决方案三: 查看详细内容登陆后才能购买解决方案四: <div align=""left""><%if((session.getAttribute(""user"")!=null)||(session.getAttribute(

内部排序算法:基数排序

基本思想 基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较.由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数. 基数排序可以采用两种方式: LSD(Least Significant Digital):从待排序元素的最右边开始计算(如果是数字类型,即从最低位个位开始). MSD(Most Significant Digital):从待排序元素的最左边开始计算(如果是数字类型,即从最高位开始). 我们以L