一、
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:
在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。
但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?
例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?(子向量的长度至少是1)
public class Solution {
//局部最优,可用贪心
//和为负数时,重新开始
public int FindGreatestSumOfSubArray(int[] array) {
int sum = 0;
int res = Integer.MIN_VALUE;
for(int i = 0; i < array.length; i++) {
sum += array[i];
res = Math.max(res, sum);
if(sum < 0) {
sum = 0;
}
}
return res;
}
}
二、
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?
为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。
ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
public class Solution {
public int NumberOf1Between1AndN_Solution(int n) {
int res = 0;
int bit = 1;
int pre = 0, cur = 0, next = 0;
while(n / bit != 0) {
cur = n / bit % 10;//当前位
pre = n / (bit * 10);//当前位的前缀
next = n - n/bit * bit;//当前位的后缀
//若当前位为0,则1的个数只受高位影响
if(cur == 0) {
res += bit * pre;
//若当前位为1,需要再加上从后缀全为0到该位个1
}else if(cur == 1) {
res += bit * pre + next + 1;
//若当前位大于1,需要再加上bit个1;和当前位为1的区别在于,完整和不完整的区别,类似998和1000的区别
}else {
res += bit * pre + bit;
}
bit *= 10;
}
return res;
}
}
三、
输入一个正整数数组,把数组里所有数字拼接起来排成一个数
打印能拼接出的所有数字中最小的一个。
例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
public class Solution {
//使用API让compartor帮我们排序
public String PrintMinNumber(int [] numbers) {
if(numbers == null || numbers.length == 0) {
return "";
}
String[] strs = new String[numbers.length];
for(int i = 0; i < numbers.length; i++) {
strs[i] = String.valueOf(numbers[i]);
}
Arrays.sort(strs, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return (o1+o2).compareTo(o2+o1);
}
});
StringBuffer sb = new StringBuffer();
for(int i = 0; i < numbers.length; i++) {
sb.append(strs[i]);
}
return sb.toString();
}
}
四、
把只包含因子2、3和5的数称作丑数(Ugly Number)。
例如6、8都是丑数,但14不是,因为它包含因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
public class Solution {
//计算所有前N个丑数,输出第N个
public int GetUglyNumber_Solution(int index) {
if(index == 0) {
return 0;
}
int[] ugly = new int[index + 2];
ugly[0] = 1;
//用迭代法,每个丑数乘以2、3、5便又是丑数
//由于什么时候*2,什么时候*3是不确定的,分别确定三个指针
int two = 0, three = 0, five = 0;
for(int i = 1; i < index; i++) {
ugly[i] = Math.min(ugly[two] * 2, Math.min(ugly[three] * 3, ugly[five] * 5));
if(ugly[i] == ugly[two] * 2) {
two++;
}
if(ugly[i] == ugly[three] * 3) {
three++;
}
if(ugly[i] == ugly[five] * 5) {
five++;
}
}
return ugly[index - 1];
}
}
五、
在一个字符串(1<=字符串长度<=10000,全部由字母组成)中
找到第一个只出现一次的字符,并返回它的位置
public class Solution {
//用桶统计每个字符出现的次数,最后从头到尾遍历字符串找到出现次数为1的
public int FirstNotRepeatingChar(String str) {
int[] bucket = new int[128];
int len = str.length();
for(int i = 0; i < len; i++) {
bucket[str.charAt(i)]++;
}
for(int i = 0; i < len; i++) {
if(bucket[str.charAt(i)] == 1) {
return i;
}
}
return -1;
}
}