LeetCode刷题记录(四)
1、数组拆分 I
题目:
我的思路:
这一题我的思路分为两步:首先要将这个数组中的元素进行排序,使其成为一个有序数组,然后挑选出其中第奇数个元素,将它们相加的和就是结果。
为什么是第奇数个元素相加呢?根据题目中要求,要选出两两组合中较小的元素相加然后得到最大的总和,所以我们就要使两两组合中较小的那个元素尽量大,因为已经先对这个数组进行了排序,所以这2n个数中值最大的元素就是第2n个数,它是不可能被选出来的,那么比2n小但是比其他的元素都大的数是第2n-1个数,因此它可以被选中,以此类推,我们继续从剩下的2n-2个元素中继续挑选较大的元素,都是奇数索引所对应的元素。
按照这个思路实现的代码如下:
class Solution {
public int arrayPairSum(int[] nums) {
//1、先排序
for (int i = 1; i < nums.length; i++) {
int get = nums[i];
int left = 0;
int right = i - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (nums[mid] > get)
right = mid - 1;
else
left = mid + 1;
}
for (int j = i - 1; j >= left; j--)
{
nums[j + 1] = nums[j];
}
nums[left] = get;
}
//2、获取第奇数个数相加
int rslt = 0;
for(int a = 0; a < nums.length; a = a + 2) {
rslt += nums[a];
}
return rslt;
}
}
反思:
这一题我是自己写的一个排序方法,可能效率不高,其实可以调用Java提供的数组排序方法。
2、两数之和 II - 输入有序数组
题目:
我的思路:
- 因为这个数组是升序排列的,所以可以定义两个指针i和j分别指向数组的第一个元素和最后一个元素;
- 判断target减去j指向的元素,得到的结果如果小于i指向的元素,那么说明j指向的元素较大,因此j要向前移,如果得到的结果大于i指向的元素,说明i指向的元素较小,i要向后移,这样移动i和j直到得到结果为止。
按照这个思路实现的代码如下:
class Solution {
public int[] twoSum(int[] numbers, int target) {
int i = 0, j = numbers.length - 1;
int[] rslt = new int[2];
while(i < j) {
if(target - numbers[j] < numbers[i]) {
//1、j指向的值较大,j向前移
j--;
} else if(target - numbers[j] > numbers[i]) {
//2、i指向的值较小,i向后移
i++;
} else {
rslt[0] = i + 1;
rslt[1] = j + 1;
break;
}
}
return rslt;
}
}
3、移除元素
题目:
我的思路:
- 因为题目要求要原地移除元素,所以不能定义新的数组,可以定义两个指针i和j分别指向数组第一个元素和最后一个元素;
- 从前向后遍历数组,如果i指向的元素和要移除的元素值相同,那么替换i指向元素的值为j指向的元素,同时j指针向前移动一位,否则直接将i指针向后移动一位;
- 这样移动i和j指针直到两个指针相遇。
按照这个思路实现的代码如下:
class Solution {
public int removeElement(int[] nums, int val) {
if(nums == null || nums.length == 0) {
return 0;
}
if(nums.length == 1 && nums[0] == val) {
return 0;
} else if(nums.length == 1