题目描述
给定一个字符串str,只由’X’和’.'两种字符构成 ‘X’表示墙,不能放灯,也不需要点亮;’.'表示街道,可以放灯,需要点亮 如果灯放在i位置,可以让i-1,i和i+1三个位置被点亮 返回如果点亮str中所有需要点亮的位置,至少需要几盏灯
贪心算法
解题思路
因为碰到墙不能放灯,所以我们就统计墙中间有多少街道,一个灯可以照亮三个街道,所以,每次碰到墙,就统计街道的数量,再下一个墙后面清零重新计算街道的数量,把灯的数量相加.
代码演示
/**
* 每三个路需要一个灯
* @param str
* @return
*/
public static int getMinLight(String str){
if (null == str || str.equals("")){
return 0;
}
char[] chars = str.toCharArray();
int light = 0;
int point = 0;
for (int i = 0; i < chars.length;i++){
if (chars[i] == 'X'){
//计算需要的灯数
light = (light + 2)/3;
point = 0;
}else {
point++;
}
}
//最后没有遇到墙的话,把需要的灯也加上
light += (point + 2)/3;
return light;
}
递归解法
/**
*
* @param chs
* @param index 当前位置
* @param lights 放灯的数组
* @return
*/
public static int process(char[]chs, int index, HashSet<Integer>lights){
if (index == chs.length){
for (int i = 0; i < chs.length;i++){
if (chs[i] != 'X'){
if (!lights.contains(i - 1) && !lights.contains(i) && !lights.contains(i + 1)){
return Integer.MAX_VALUE;
}
}
}
return lights.size();
}else{
int no = process(chs,index + 1,lights);
int yes = Integer.MAX_VALUE;
if (chs[index] == '.'){
lights.add(index);
yes = process(chs,index + 1,lights);
lights.remove(index);
}
return Math.min(no,yes);
}
}
/**
* 调用递归函数
* @param str
* @return
*/
public static int minLight(String str){
if (str == null || str.equals("")){
return 0;
}
return process(str.toCharArray(),0,new HashSet<Integer>());
}