数组中出现次数超过一半的数字
题目描述:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
public
class
Solution {
/**
* 采用阵地攻守的思想: 第一个数字作为第一个士兵,守阵地;count = 1;
* 遇到相同元素,count++; 遇到不相同元素,即为敌人,同归于尽,count--;
* 当遇到count为0的情况,又以新的i值作为守阵地的士兵,继续下去,到最后还留在阵地上的士兵,
* 有可能是主元素。 再加一次循环,记录这个士兵的个数看是否大于数组一般即可。
* @param array
* @return
*/
public
int
MoreThanHalfNum_Solution(
int
[] array) {
int
length = array.length;
if
(array ==
null
|| length <=
0
) {
return
0
;
}
int
result = array[
0
];
int
times =
1
;
for
(
int
i =
1
; i < length; i++) {
if
(times ==
0
) {
result = array[i];
times =
1
;
}
else
{
if
(array[i] == result) {
times++;
}
else
{
times--;
}
}
}
times =
0
;
for
(
int
i =
0
; i < length; i++) {
if
(result == array[i]) {
times++;
}
}
if
(times *
2
< length) {
result =
0
;
}
return
result;
}
}
|
最小的K个数
题目描述:
输入n个整数,找出其中最小的K个数。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。
import
java.util.ArrayList;
public
class
Solution {
/**
* 最小的K个数
* @param input
* @param k
* @return
*/
public
ArrayList<Integer> GetLeastNumbers_Solution(
int
[] input,
int
k) {
ArrayList<Integer> aList =
new
ArrayList<Integer>();
if
(input.length < k || input ==
null
) {
return
aList;
}
if
(k ==
0
) {
return
aList;
}
int
len = input.length;
findSort(input,
0
, len -
1
, k);
for
(
int
i=
0
;i<k;i++){
aList.add(input[i]);
}
return
aList;
}
/*
递归查找
*/
private void findSort(int[] input, int p, int r, int k) {
if (p == r) {
return;
}
int q = partition(input, p, r);
int temp = q - p + 1;///当前的长度
if (temp == k) {
return;
} else if (k < temp) {
findSort(input, p, q - 1, k);
} else {
findSort(input, q + 1, r, k - temp);
}
}
/*
分治法来实现最小k的查找/*
*/
private
int
partition(
int
[] input,
int
p,
int
q) {
int
x = input[q];
int
i = p -
1
;
for
(
int
j = p; j < q ; j++) {
if
(input[j] <= x) {
i = i +
1
;
int
temp = input[i];
input[i] = input[j];
input[j] = temp;
}
}
input[q] = input[i +
1
];
input[i +
1
] = x;
return
i +
1
;
}
}
|
连续子数组的最大和
题目描述:
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。你会不会被他忽悠住?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
public
class
Solution {
/*
分治法求解最大字数组 这个算法自己曾经实现过 不过有些问题没有解决
*/
public
int
FindGreatestSumOfSubArray(
int
[] array) {
if
(array.length ==
0
|| array ==
null
) {
return
0
;
}
int
result = findMaxSubArray(array,
0
, array.length -
1
);
return
result;
}
private
int
findMaxSubArray(
int
[] arr,
int
left,
int
right) {
int
result=
0
;
if
(left == right) {
result=arr[left];
return
result;
}
else
{
int
mid = (left + right) /
2
;
int
saleft = findMaxSubArray(arr, left, mid);
int
saright = findMaxSubArray(arr, mid+
1
, right);
int
sacross = findCrossingMaxSubArray(arr, left, mid,
right);
if
(saleft > saright
&& saleft > sacross) {
return
saleft;
}
else
if
(saright > saleft
&& saright > sacross) {
return
saright;
}
else
{
return
sacross;
}
}
}
private
int
findCrossingMaxSubArray(
int
[] arr,
int
left,
int
mid,
int
right) {
int
sum=
0
;
int
begin=
0
;
int
end=
0
;
int
leftsum = arr[mid] ;
sum=arr[mid];
for
(
int
i=mid-
1
;i>=left;i--){
sum=sum+arr[i];
if
(sum>leftsum){
leftsum=sum;
begin=i;
}
}
int
rightsum = arr[mid+
1
];
sum=arr[mid+
1
];
for
(
int
i=mid+
2
;i<=right;i++){
sum=sum+arr[i];
if
(sum>rightsum){
rightsum=sum;
end=i;
}
}
return
leftsum+rightsum;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public
class
Solution {
public
static
int
FindGreatestSumOfSubArray(
int
[] array) {
if
(array.length==
0
)
return
0
;
int
sum =
0
,result = array[
0
];
for
(
int
i =
0
; i < array.length; i++) {
if
(sum<
0
)
sum = array[i];
else
sum += array[i];
result = Math.max(result, sum);
}
return
result;
}
}
|
题目描述:
求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。
把数组排成最小的数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
public
class
Solution {
public
int
NumberOf1Between1AndN_Solution(
int
n) {
if
(n<=
0
){
return
0
;
}
String str = Integer.toString(n);
char
[] strN=str.toCharArray();
return
NumberOf1(strN,
0
);
}
private
int
NumberOf1(
char
[] strN,
int
loc) {
if
(strN==
null
||strN[loc]<
'0'
||strN[loc]>
'9'
||strN[loc]==
'\0'
){
return
0
;
}
int
first=strN[loc]-
'0'
;
//剩余长度
int
len = strN.length-loc;
//剩余 长度 下标是从0开始
if
(len==
1
&&first==
0
){
return
0
;
}
if
(len==
1
&&first>
0
){
return
1
;
}
int
numFirstDigit=
0
;
if
(first>
1
){
numFirstDigit=PowerBase10(len-
1
);
}
else
if
(first==
1
){
numFirstDigit=Atoi(strN,loc+
1
)+
1
;
//将后序的字符转换成为数值
}
//除了开头第一位的所有其他的四位数中的情况
int
numOtherDigit=first*(len-
1
)*PowerBase10(len-
2
);
int
numRecursive = NumberOf1(strN, loc+
1
);
return
numFirstDigit+numOtherDigit+numRecursive;
}
private
int
Atoi(
char
[] strN,
int
loc) {
int
num =
0
;
for
(
int
i=loc;i<strN.length;i++){
num=num*
10
+(strN[i]-
'0'
);
}
return
num;
}
private
int
PowerBase10(
int
n) {
int
res=
1
;
for
(
int
i=
0
;i<n;i++){
res*=
10
;
}
return
res;
}
}
|
题目描述:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
import
java.util.ArrayList;
public
class
Solution {
/**
* 生成最小数值的数组排列 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
* 例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
*
* @param numbers
* @return
*
* 这个题目主要是想找到一个排序规则,数组根据这个排序规则来排成一个最小的数字。要确定排序规则就要比较两个数字,也就是比较
* m和n,我们需要一个规则判断m和n哪一个应该排在前面,而不是仅仅比较两个数字的值哪个更大。
*
* 根据题目要求,两个数字m和n 拼接成为mn和nm如果mn小于nm,那么我们应该打印出mn,也就是m应该排在n 的前面。
* 我们定义此时m<n.这是我们自定义的大小比较关系。
*
* 拼接称为字符串,按照字符串比较大小就可以了。
*/
public
String PrintMinNumber(
int
[] numbers) {
if
(numbers.length ==
0
|| numbers ==
null
) {
return
""
;
}
int
len = numbers.length;
String[] strNums =
new
String[len];
for
(
int
i =
0
; i < len; i++) {
strNums[i] = Integer.toString(numbers[i]);
// construct string from a int array
}
String res = qSortStrArray(strNums, len);
return
res;
}
private
String qSortStrArray(String[] strNums,
int
len) {
if
(strNums ==
null
|| strNums.length ==
0
)
return
null
;
for
(
int
i=
0
;i<len-
1
;i++){
for
(
int
j=i;j<len;j++){
if
((strNums[i]+strNums[j]).compareTo(strNums[j]+strNums[i])>
0
){
String temp = strNums[i];
strNums[i]=strNums[j];
strNums[j]=temp;
}
}
}
String res=
""
;
for
(
int
i=
0
;i<len;i++){
res+=strNums[i];
}
return
res;
}
}
|