玖雨y的算法刷题记录day14——数组
本篇选择了 Leetcode 题库中有关数组的几道题目,涉及二分查找、Stream流、双指针、哈希表法等知识点。
- 题目链接:有多少小于当前数字的数字
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class Leetcode_1365 {
public int[] smallerNumbersThanCurrent(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
int[] res = Arrays.copyOf(nums, nums.length);
bubbleSort(res);
for (int i = 0; i < res.length; i++) {
if (!map.containsKey(res[i])) { // 遇到了相同的数字,那么不需要更新该 number 的情况
map.put(res[i], i);
}
}
for (int i = 0; i < nums.length; i++) {
res[i] = map.get(nums[i]);
}
return res;
}
public void bubbleSort(int[] nums) {
int j = nums.length - 1;
do {
int x = 0;
for (int i = 0; i < j; i++) {
if (nums[i] > nums[i + 1]) {
int temp = nums[i + 1];
nums[i + 1] = nums[i];
nums[i] = temp;
x = i;
}
}
j = x;
} while (j != 0);
}
}
- 题目链接:有效的山脉数组
public class Leetcode_941 {
public boolean validMountainArray(int[] arr) {
if (arr.length < 3) return false;
int i = 0;
while (i < arr.length - 1 && arr[i] < arr[i + 1]) {
i++;
}
if (i == 0 || i == arr.length - 1) return false;
while (i < arr.length - 1 && arr[i] > arr[i + 1]) {
i++;
}
return i == arr.length - 1;
}
}
- 题目链接:独一无二的出现次数
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class Leetcode_1207 {
public boolean uniqueOccurrences(int[] arr) {
Map<Integer, Long> map = Arrays.stream(arr).boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
return map.values().stream().distinct().count() == map.size();
}
}
- 题目链接:移动零
import java.util.Arrays;
public class Leetcode_283 {
public static void moveZeroes(int[] nums) {
int slow = 0;
for (int fast = 0; fast < nums.length; fast++) {
if (nums[fast] != 0) {
nums[slow++] = nums[fast];
}
}
for (int j = slow; j < nums.length; j++) {
nums[j] = 0;
}
}
public static void main(String[] args) {
int[] nums = {0, 1, 0, 3, 12, 5, 0, 7};
moveZeroes(nums);
System.out.println(Arrays.toString(nums));
}
}
- 题目链接:旋转数组
public class Leetcode_189 {
private void reverse(int[] nums, int start, int end) {
for (int i = start, j = end; i < j; i++, j--) {
int temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}
public void rotate(int[] nums, int k) {
int n = nums.length;
k %= n;
reverse(nums, 0, n - 1);
reverse(nums, 0, k - 1);
reverse(nums, k, n - 1);
}
}
- 题目链接:寻找数组的中心下标
import java.util.Arrays;
public class Leetcode_724 {
public int pivotIndex(int[] nums) {
int totalSum = Arrays.stream(nums).sum();
int leftSum = 0;
for (int i = 0; i < nums.length; i++) {
if (leftSum == totalSum - leftSum - nums[i]) {
return i;
}
leftSum += nums[i];
}
return -1;
}
}
public class Leetcode_34 {
public int[] searchRange(int[] nums, int target) {
int index = binarySearch(nums, target); // 二分查找
if (index == -1) { // nums 中不存在 target,直接返回 {-1, -1}
return new int[]{-1, -1}; // 匿名数组
}
// nums 中存在 target,则左右滑动指针,来找到符合题意的区间
int left = index;
int right = index;
// 向左滑动,找左边界
while (left - 1 >= 0 && nums[left - 1] == nums[index]) { // 防止数组越界。逻辑短路,两个条件顺序不能换
left--;
}
// 向右滑动,找右边界
while (right + 1 < nums.length && nums[right + 1] == nums[index]) { // 防止数组越界。
right++;
}
return new int[]{left, right};
}
public int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 不变量:左闭右闭区间
while (left <= right) { // 不变量:左闭右闭区间
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1; // 不变量:左闭右闭区间
}
}
return -1; // 不存在
}
}
- 题目链接:按奇偶排序数组II
import java.util.Arrays;
public class Leetcode_922 {
public static int[] sortArrayByParityII(int[] nums) {
//定义双指针
int oddPoint = 1, evenPoint = 0;
//开始移动并交换,最后一层必然为相互交换后再移动或者相同直接移动
while (oddPoint < nums.length && evenPoint < nums.length) {
//进行判断
if (nums[oddPoint] % 2 == 0 && nums[evenPoint] % 2 == 1) { //如果均不满足
int temp = nums[oddPoint];
nums[oddPoint] = nums[evenPoint];
nums[evenPoint] = temp;
oddPoint += 2;
evenPoint += 2;
} else if (nums[oddPoint] % 2 == 0 && nums[evenPoint] % 2 == 0) { //偶数满足
evenPoint += 2;
} else if (nums[oddPoint] % 2 == 1 && nums[evenPoint] % 2 == 1) { //奇数满足
oddPoint += 2;
} else {
oddPoint += 2;
evenPoint += 2;
}
}
return nums;
}
public static void main(String[] args) {
int[] nums = {4, 2, 5, 7};
System.out.println(Arrays.toString(sortArrayByParityII(nums)));
}
}
- 题目链接:搜索插入位置
public class Leetcode_35 {
public static int searchInsert(int[] nums, int target) {
int l = 0;
int r = nums.length - 1;
while (l <= r) {
int m = l + ((r - l) >> 1);
if (nums[m] < target) {
l = m + 1;
} else if (nums[m] > target) {
r = m - 1;
} else {
return m;
}
}
return l;
}
public static void main(String[] args) {
int[] nums = {1, 3, 5, 6};
int target = 7;
System.out.println(searchInsert(nums, target));
}
}