day5题目: 7. 整数反转 、215. 数组中的第K个最大元素 、23. 合并K个升序链表
学习计划链接:冲刺春招-精选笔面试 66 题大通关
今日知识点:数学、数组、快排,难度为中等、中等、困难
7. 整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1: 输入:x = 123 输出:321
思路
整数反转-题解 看了题解才晓得,是数学题嗷,通过不等式变换 这我是真没想到() 取巧一些的话就用long long存防止溢出
完整代码
复制 class Solution {
public :
int reverse ( int x ) {
int ans = 0 ;
while (x) {
if (ans > INT_MAX / 10 || ans < INT_MIN / 10 ) return 0 ;
ans = (ans * 10 ) + x % 10 ;
x /= 10 ;
}
return ans;
}
};
215. 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1: 输入: [3,2,1,5,6,4] 和 k = 2 输出: 5
示例 2: 输入: [3,2,3,1,2,4,5,5,6] 和 k = 4 输出: 4
思路
取巧一点就直接调sort排好序之后返回。 否则的话手写快排咯~~具体可以看排序那期的学习笔记:数据结构学习笔记<8> 排序
完整代码
暴力(时间反而很快
复制 class Solution {
public :
int findKthLargest ( vector < int > & nums , int k) {
sort ( nums . begin () , nums . end () , greater < int >());
return nums [k - 1 ];
}
};
手写快排,主元在s~e中随机抽取以避免最坏情况。
复制 class Solution {
public :
int quickSort ( vector < int > & nums , int k , int s , int e) {
int idx = rand () % (e - s + 1 ) + s;
int m = nums [idx]; // 主元为s~e中随机的一个
int l = s , r = e;
nums [idx] = nums [l];
while (l != r) {
while (l < r && nums [r] <= m) -- r; // 遇到右边有比他大的才停下
nums [l] = nums [r];
while (l < r && nums [l] >= m) ++ l;
nums [r] = nums [l];
} // 处理完后主元m到了正确的位置nums[l],左边元素都比他大,右边元素都比他小
nums [l] = m;
if (l == k - 1 ) return nums [l];
else if (l > k - 1 ) return quickSort (nums , k , s , l - 1 ); // 快排左边部分
else return quickSort (nums , k , l + 1 , e);
}
int findKthLargest ( vector < int > & nums , int k) {
int len = nums . size ();
return quickSort (nums , k , 0 , len - 1 );
}
};
23. 合并K个升序链表
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1: 输入:lists = [[1,4,5],[1,3,4],[2,6]] 输出:[1,1,2,3,4,4,5,6] 解释:链表数组如下: [ 1->4->5, 1->3->4, 2->6 ] 将它们合并到一个有序链表中得到。 1->1->2->3->4->4->5->6
思路
day1就写过合并两个有序链表,这次的只需要暴力就好了。 但要优化的话,可以使用优先队列每次链表头的结点,取出最顶上的结点放至答案链表后。
完整代码
暴力版
复制 /**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
var mergeList = function (list1 , list2) {
let p1 = list1;
let p2 = list2;
if ( ! p1 && ! p2) return null ;
else if ( ! p1) return p2;
else if ( ! p2) return p1;
else if ( p1 .val <= p2 .val) {
p1 .next = mergeList ( p1 .next , p2);
return p1;
} else {
p2 .next = mergeList ( p2 .next , p1);
return p2;
}
}
/**
* @param {ListNode[]} lists
* @return {ListNode}
*/
var mergeKLists = function (lists) {
let ans = null ;
let len = lists . length ;
for ( let i = 0 ; i < len; ++ i) {
ans = mergeList (ans , lists[i]);
}
return ans;
};
优先队列版
复制 /**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public :
struct Node {
int val;
ListNode * nowp;
bool operator <( const Node & p1) const {
return val > p1 . val;
}
};
ListNode * mergeKLists ( vector < ListNode * > & lists) {
priority_queue < Node > q;
ListNode head;
ListNode * tail = & head;
for ( auto h : lists) {
if (h) q . push ({ h -> val , h});
}
while ( ! q . empty ()) {
Node nowv = q . top ();
q . pop ();
tail -> next = nowv . nowp;
tail = tail -> next;
ListNode * nexp = nowv . nowp -> next;
if (nexp) q . push ({ nexp -> val , nexp});
}
return head . next;
}
};