第一题:旋转数组的最小数字
把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
例如输入数组[1, 2, 3, 4, 5],将它变成旋转数组比如[3, 4, 5, 1, 3]或者[4, 5, 1, 2, 3]。
输入一个非递减排序的数组,将它进行旋转,求旋转数组的最小值。
NOTE:给出的所有元素都大于0,若数组大小为 0,请返回 0。
// 示例1
输入:[3, 4, 5, 1, 2]
返回:1
// 示例2
输入:[3, 100, 200, 3]
返回:3
方法一:先将数组从小到大排序,arr[0]即为最小值。可以使用JavaScript中的sort()函数排序。sort()参数是一个比较函数,如果没有参数是按照各个字符的 Unicode 编码排序。
// 当没有参数传入时,默认按照数组转成字符串后的结果每一位的 Unicode 编码进行排序
let arr = [311, 43, 54, 4, 40, 26, 31, 33];
arr.sort();
console.log(arr); // [26, 31, 311, 33, 4, 40, 43, 54]
function minNumberInRotateArray (rotateArray) {
if (rotateArray.length === 0) return 0;
function compare (value1, value2) {
return value1 > value2 ? 1 : 0;
}
rotateArray.sort(compare);
return rotateArray[0];
}
问题:关于比较函数的返回值规则如下:
(1)返回结果小于 0,则 value1、value2 顺序不变。
(2)返回结果等于 0,则 value1、value2 顺序不变。
(3)返回结果大于 0,则 value1、value2 交换位置。
相当于返回值结果大于 0 时才会交换位置,否则顺序不变。也就是返回值可能出现的情况只有两种,是否可以用布尔值代替呢?比如上面的比较函数可以改写如下,测试通过也没问题。
function compare (value1, value2) {
return value1 > value2;
}
方法二:使用 Math.min()
function minNumberInRotateArray (rotateArray) {
return rotateArray.length === 0 ? 0 : Math.min(...rotateArray);
}
第二题:二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
[
[1, 2, 8, 9],
[2, 4, 9, 12],
[4, 7, 10, 13],
[6, 8, 11, 15]
]
一、Java 实现
(1)遍历数组,如果找到就返回 true
public class Solution {
public boolean Find(int target, int [][] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
if (array[i][j] == target) {
return true;
}
}
}
return false;
}
}
(2)从二维数组左下角开始找:利用每行每列递增的特点,target 大于当前值,向右移动 j++;target 小于当前值,向上移动 i–
public class Solution {
public boolean Find(int target, int [][] array) {
int rows = array.length;
if (rows == 0) {
return false;
}
int cols = array[0].length;
if (cols == 0) {
return false;
}
// 左下
int row = rows - 1; // 起始行号
int col = 0; // 起始列号
while (row >= 0 && col < cols) {
if (array[row][col] < target) {
col++;
} else if (array[row][col] > target) {
row--;
} else {
return true;
}
}
return false;
}
}
二、JavaScript 实现
// 从左下找
function Find (target, array) {
if (!target || !array || array.length === 0 || array[0].length === 0) {
return false;
}
let row = array.length - 1; // 起始行号
let col = 0; // 起始列号
while (row >= 0 && col < array[0].length) {
if (array[row][col] < target) {
col++;
} else if (array[row][col] > target) {
row--;
} else {
return true;
}
}
return false;
}
第三题:计算最大收益
某人连续几天的股票涨跌情况用一数组表示,计算卖出后能获得的最大收益。
// 示例1
输入:[1, 6, 4, 3, 5]
返回:5
因为第一天是 1,第二天是 6,可获最大收益是 5
// 示例2
输入:[7, 6, 5, 4, 3, 2]
返回:0
因为一直在下降,可获最大收益是 0
function getFullProfit (arr) {
var count = 0;
arr.forEach((i, arr) => {
if (arr[i] > arr[i+1]) {
count++;
}
})
if (count === arr.length-1) {
return 0;
} else {
var max = Math.max(...arr);
var min = Math.min(...arr);
var res = max - min;
return res;
}
}
第四题:对象数组去重
// 示例1
输入:[{a:1,b:'vio'},{a:2,b:'asd'},{a:3,b:'zxc'},{a:1,b:'vio'},{a:4,b:'efg'}]
返回:[{a:1,b:'vio'},{a:2,b:'asd'},{a:3,b:'zxc'},{a:4,b:'efg'}]
方法一:使用 reduce() 方法
function unique (arr) {
let obj = {};
arr = arr.reduce((pre, cur) => {
obj[cur.a] ? ' ' : obj[cur.a] = true && pre.push(cur)
return pre;
}, [])
return arr;
}
reduce 的语法: array.reduce(callback, [initialValue])
initialValue是 callback 初次调用时的第一个参数值。
callback函数的四个参数:
1. previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2. currentValue (数组中当前被处理的元素)
3. index (当前元素在数组中的索引)
4. array (调用 reduce 的数组)
方法二:判断对象中是否存在某个 key
function unique (arr) {
var res = [];
var obj = {};
arr.forEach((item, index) => {
if (!obj[arr[index].a]) {
res.push(arr[index]);
obj[arr[index].a] = true;
}
})
return res;
}