BM50两数之和
题目描述:给出一个整型数组 numbers 和一个目标值 target,请在数组中找出两个加起来等于目标值的数的下标,返回的下标按升序排列。
解题思路:
一般的暴力搜索思路在这里我们不做赘述,首先我们看到该题的返回值一定是一个长度为2
的int型数组,用来保存符合题意的元素的下标(注意:题目要求下标是从1开始的),所以我们创建一个数组,接下来我们创建一个hashmap用来映射数组中的元素与下标之间的关系,遍历题中给出的数组,如果target减去当前的元素可以在hashmap中找到那么这两个元素的下标一定是题目要求返回的结果,如果不是的话我们把当前的元素放入map即可,以防后面使用。
代码描述:
public int[] twoSum (int[] numbers, int target) {
int[] array = new int[2];
HashMap<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < numbers.length; i++) {
int num = target - numbers[i];
if(map.containsKey(num)){
array[0] = map.get(num) + 1;
array[1] = i + 1;
break;
}else{
map.put(numbers[i],i);
}
}
return array;
}
BM51 数组中出现次数超过一半的数字
题目描述:
给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
思路分析:我们创建一个hashmap来映射数组中的某元素与该元素在数组中出现的次数,然后遍历整个数组,如果map中没有该元素则把该元素放进去,并使它的value值为一,如果map中有该元素我们先要得到该元素之前出现的次数,并且让该key对应的value值加一,最后判断该key值所对应的value是否已经大于数组长度的一半。
代码描述:
public int MoreThanHalfNum_Solution(int [] array) {
int num = 0;
HashMap<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < array.length; i++) {
if(map.containsKey(array[i])){
int value = map.get(array[i]);
map.put(array[i],value + 1);
}else{
map.put(array[i],1);
}
if(map.get(array[i]) > array.length / 2){
num = array[i];
break;
}
}
return num;
}
BM52 数组中只出现一次的两个数字
题目描述:一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路分析:
我们创建一个hashmap映射该元素与其在数组中出现的次数(题目中描述不是为1,就是为2)所以在往map中放元素的时候只需要判断map中有无该元素如果有的话只需要把其value值覆盖为2即可,如果没有的话设置其value值为1。最后遍历map如果某元素的value值为1的话,把它保存到要返回的数组中,由于题目要求把小的元素放在前面,所以我们调用Arrays的sort方法对目标数组进行排序。
代码描述:
public int[] FindNumsAppearOnce(int[] array) {
int[] result = new int[2];
HashMap<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < array.length; i++) {
if(! map.containsKey(array[i])){
map.put(array[i],1);
}else{
map.put(array[i],2);
}
}
int index = 0;
for (Map.Entry<Integer,Integer> entry:map.entrySet()) {
if(entry.getValue() == 1){
result[index] = entry.getKey();
index ++;
}
}
Arrays.sort(result);
return result;
}
BM53 缺失的第一个正整数
题目描述:
给定一个无重复元素的整数数组nums,请你找出其中没有出现的最小的正整数
思路分析:
众所周知,最小的正整数为一,我们首先创建一个变量num为1,然后创建一个hashset容器,遍历整个数组,把数组中的元素放入set中,如果num在set中可以找到那么就让num一直进行加一操作,直到set中不包含num为止,遍历完整个数组返回num值即可。
代码描述:
public int minNumberDisappeared1 (int[] nums) {
int num = 1;
HashSet<Integer> set = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
set.add(nums[i]);
while(set.contains(num)){
num ++;
}
}
return num;
}
BM54 三数之和
题目描述:给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组
思路分析:
首先我们对数组进行从小到大的排序。
我们进行循环选择第一个数num[i],然后创建两个指针left和right,指针left指向下一个数,指针j指向最后一个数。
如果num[i] + num[left] +num[right]<0那么就让left指针往右走;
如果num[i] + num[left] +num[right]>0那么就让right指针往左走;
如果num[i] + num[left] +num[right]==0那么就应该保存这三个数;
以上就是我们的 大致思路,但题目中还要求了这个三元组不能重复,那么就要考虑去重,我们发现在num[i] + num[left] +num[right]==0时为了不漏解我们必须要让left和right指针相遇,但是这样一来我们就可能得到同样的num[left]和num[right],由于我们事先对num数组进行了排序所以即使有重复的值那么它必定是相连的,此时只要让指针继续走就行,不必判断这组;同理如果遇到相同的num[i]也让i继续++即可,这样便可以做到去重。
代码描述:
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
if(num.length < 3){
return result;
}
Arrays.sort(num);
for (int i = 0; i < num.length - 2;) {
int left = i + 1;
int right = num.length -1;
if(num[i] > 0){
return result;
}
while (left < num.length - 1 && right > 0 &&left < right ){
int number = num[i] + num[left] + num[right];
if(number == 0){
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(num[i]);
arrayList.add(num[left]);
arrayList.add(num[right]);
result.add(arrayList);
if(num[left + 1] == num[left]){
while(left < num.length - 2 &&num[left + 1] == num[left]){
left++;
}
}
left++;
if(num[right - 1] == num[right]){
while(right > 0 && num[right - 1] == num[right]){
right--;
}
}
right--;
}else if(number > 0){
right--;
}else if(number < 0){
left ++;
}
if(!(left < right)){
break;
}
}
if(num[i + 1] == num[i]) {
while(i < num.length - 2 && num[i + 1] == num[i]){
i++;
}
}
i++;
}
return result;
}