图片源自:力扣
该题的关键在于找到扑克牌连子的规律,如果五张牌连着,在不考虑癞子牌的情况下无论如何都应是最大牌减最小牌为4。
如果再去掉癞子并且不考虑重复牌的情况下,应该是小于5(比如00125,00235无论怎样都会是小于五,因为没有重复牌的情况下,最多会有两个癞子,如果满足链子的情况下,只要其最大减最小会小于五,加上癞子总会满足情况)
使用集合来确认有重复牌直接return false;
设牌最小为14,牌最小为0,方便确定最大牌点数与最小牌点数。
code:
/**
* @param {number[]} nums
* @return {boolean}
*/
var isStraight = function(nums) {
var set = new Set();
var minnum = 14,maxnum = 0;
for(var i of nums){
if(i==0)continue;
if(set.has(i)) return false;
maxnum = Math.max(maxnum,i);
minnum = Math.min(minnum,i);
set.add(i);
}
return maxnum - minnum < 5
};
该题需要将时间复杂度降为n^2以下,容易想到使用快速排序,其时间复杂度为nlogn,可以ac
思想:
定义数组开头的数为“哨兵”,之后从数组的最右边开始向左寻找小于哨兵的值(无论如何应该从哨兵的另一边开始进行寻找。。从左开始左边会停留在一个大于哨兵值的数,但是右边开始走可能也刚好到该数停下,导致该数去了开头违反排序。),如果小于将该值赋值给左指针,再从左向右寻找大于哨兵的值,如果大于则将其赋值给右指针,左右指针相等时将开始时的哨兵值赋值给它。
code:
/**
* @param {number[]} arr
* @param {number} k
* @return {number[]}
*/
var getLeastNumbers = function(arr, k) {
var partition = function(arr,start,end){
if(start>=end){
return;
}
var i = start;
var j = end;
var temp_0 = arr[i];
while (i<j){
while(temp_0<arr[j] && j>i) j--;
arr[i] = arr[j];
while(temp_0>=arr[i] && j > i) i++;
arr[j] = arr[i];
}
arr[j] = temp_0;
partition(arr,start,j-1);
partition(arr,j+1,end);
}
partition(arr, 0, arr.length-1);
return arr.splice(0,k)
};
优化:该题仅要求输出前k个,因此在排序时可以返回排序最后的index,对比index与k的大小
如果k大于index,则只需要对后半部分进行排序,将start值更改为index+1,
如果k小于index,则需要对前半部分进行排序,将end改为index-1
由于快速排序的特点,基准点为k时即为最后结果
code:
/**
* @param {number[]} arr
* @param {number} k
* @return {number[]}
*/
var getLeastNumbers = function(arr, k) {
var partition = function(arr,start,end){
// if(start>=end){
// return;
// }
var i = start ;
var j = end;
var temp_0 = arr[i];
while (i<j){
while(temp_0<arr[j] && j>i) j--;
arr[i] = arr[j];
while(temp_0>=arr[i] && j > i) i++;
arr[j] = arr[i];
}
arr[j] = temp_0;
return j
}
var right = arr.length-1;
var left = 0
var index = partition(arr, left, right);
while (k!=index && k!=(index+1)){
console.log(index);
if (k> index){
left = index+1;
index = partition(arr,left, right);
}
else if(k< index){
right = index-1;
index = partition(arr,left,right);
}
}
return arr.splice(0,k);
};
同样是对排序的应用,但是该题需要将排序的判断条件修改为符合题意的两个数字结合最小的情况。
''+temp_0+arr[j]<=''+arr[j]+temp_0 此情况为temp0小于一个arr[j]的值,例如:13<31,所以temp0“小于”arr[j],将此条件修改到快速排序即可。
code:
/**
* @param {number[]} nums
* @return {string}
*/
var minNumber = function(nums) {
var partition = function(arr,start,end){
if(start>=end){
return;
}
var i = start;
var j = end;
var temp_0 = arr[i];
while (i<j){
while(''+temp_0+arr[j]<=''+arr[j]+temp_0 && j>i) j--;
arr[i] = arr[j];
while(''+temp_0+arr[i]>=''+arr[i]+temp_0 && j > i) i++;
arr[j] = arr[i];
}
arr[j] = temp_0;
partition(arr,start,j-1);
partition(arr,j+1,end);
}
partition(nums,0,nums.length-1);
return nums.join('');
};
运用双指针来维护数组当中的中位数,初始化定义左右均为-1,当数组中有数添加进去后,令左右都加1得到0,此时中位数就是数组中唯一的值,之后再有任何数添加进去,先判断左右是否相等,不等则左加一,相等右加一(与奇偶原理相同)。
code:
/**
* initialize your data structure here.
*/
var MedianFinder = function() {
this.temp = [];
this.l = -1,this.r = -1;
};
/**
* @param {number} num
* @return {void}
*/
MedianFinder.prototype.addNum = function(num) {
if (this.l == -1){
this.l+=1;
this.r+=1;
}
else{
if(this.l == this.r){
this.r += 1;
}
else this.l += 1;
}
this.temp.push(num);
};
/**
* @return {number}
*/
MedianFinder.prototype.findMedian = function() {
this.temp.sort(function(a,b){return a-b});
if (!this.temp) return null;
return (this.temp[this.l]+this.temp[this.r])/2
};
/**
* Your MedianFinder object will be instantiated and called as such:
* var obj = new MedianFinder()
* obj.addNum(num)
* var param_2 = obj.findMedian()
*/