LeetCode这个网站相比不必多说了吧,凡是IT圈子的人应该都知道这个网站,最近开始准备找工作,当然也免不了上去刷刷题,做一做比较经典的编程题,刚好看到LeetCode有个周练,便报名参加。
概要: 总共4个题,一个半小时的时间安排。题目分级为,一个easy,两个medium,一个hard。
题目描述:
Given a non-negative integer c, your task is to decide whether there're two integers a and b such thata2 + b2 = c.
c的范围也不是很大,而且也暂时不知道有什么诀窍可以快速解这道题,除了枚举,所以最好的方法就是枚举,妥妥搞定;
代码如下:
class Solution {
public:
bool judgeSquareSum(int c) {
// 枚举出0到c的平方根中的数值即可
for(int i=0;i<=sqrt(c);i++){
int a = sqrt(c - i*i);
if(i*i + a*a == c) return true;
}
return false;
}
};
题目描述:
You are given several logs that each log contains a unique id and timestamp. Timestamp is a string that has the following format: Year:Month:Day:Hour:Minute:Second, for example, 2017:01:01:23:59:59. All domains are zero-padded decimal numbers.最近几周测试都有的LeetCode的类设计的题目,这种题理解起来反而很简单,而且也不难,都是偏向于业务的题目;
首先第一个方法很好实现,主要需要考虑的是文件日志系统用什么类型的数据结构来保存,联想到现在都在使用的日志系统,hash结构会比较有优势,便捷而且设计很快速;所以可以用一个hash表来存储日志信息字符串和日志的id,retrieve方法,如果没有最后那个约束条件,那就很简答了,有了约束条件,认真看看约束条件的两端,发现就是个日期大小的比对,找这个区间的日志,由于插入操作不会超过300次,所以不需要快速索引的结构,每一次遍历一遍日志系统的所有日志即可,遍历到每一条都可以代入条件中比对,符合条件即加入;
代码如下:
class LogSystem {
private:
unordered_map _table;
unordered_map _place;
unordered_map init(){
return unordered_map({
{"Year", 5},
{"Month", 8},
{"Day", 11},
{"Hour", 14},
{"Minute", 17},
{"Second", 19}
});
}
public:
LogSystem() {
_place = init();
}
void put(int id, string timestamp) {
_table[timestamp] = id;
}
vector retrieve(string s, string e, string gra) {
// 根据给定的截止条件,选择有用的字符串段来比较
int lens = _place[gra];
string start = s.substr(0, lens);
string finish = e.substr(0, lens);
vector ret;
for(auto k=_table.begin();k!=_table.end();k++){
string tmp = k->first.substr(0, lens);
// 时间上的对比直接可以用字符串的比较函数来做
if(tmp.compare(start) >= 0 && tmp.compare(finish)<=0) ret.push_back(k->second);
}
return ret;
}
};
/**
* Your LogSystem object will be instantiated and called as such:
* LogSystem obj = new LogSystem();
* obj.put(id,timestamp);
* vector param_2 = obj.retrieve(s,e,gra);
*/
题目描述:
In combinatorial mathematics, a derangement is a permutation of the elements of a set, such that no element appears in its original position.
There's originally an array consisting of n integers from 1 to n in ascending order, you need to find the number of derangement it can generate.
Also, since the answer may be very large, you should return the output mod 109 + 7.
其实不难的一个题,这个题难就难在,很多人不知道错排公式,参考维基百科;
真正写下来就跟斐波那契数列的题目一样,一个for循环就搞定了,记得取模操作;
代码如下:
// 错排公式
class Solution {
public:
int findDerangement(int n) {
const int MOD = 1000000007;
long long a1 = 0, a2 = 1;
long long ret = 0;
// 错排公式是一个类似于斐波那契数列的递归公式
// 按公式来写就好了
if(n == 1) return a1;
else if(n == 2) return a2;
else{
for(int i=3;i<=n;i++){
ret = (i-1)*(a1%MOD + a2%MOD) % MOD;
a1 = a2; a2 = ret;
}
}
return int((ret+MOD)%MOD);
}
};
题目描述:
You have k lists of sorted integers in ascending order. Find the smallest range that includes at least one number from each of the k lists.
We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c.
比较有意思的一个题,和上周那个上最多的课程有点像,利用了动态规划的思想;
用一个优先队列维护n(序列的数量)个元素,初始每个元素都是每个序列的第一位,那就可以用一个循环来做,循环里面,先统计优先队列两头的元素作为范围区间的两端,统计出这一次的范围区间大小,然后将最小的那个元素弹出,插入和这个元素同在一个序列中的元素的最小值;然后循环继续,直到优先队列大小不满足n停止循环,这个时候返回这段时间内找到的范围最小的区间两端,作为结果输出即可;
代码如下:
class Solution {
private:
typedef struct Node{
int _val;
int _row;
int _index;
Node(int row, int index, int val):
_row(row),_index(index),_val(val){}
}nd;
struct cmp{
bool operator()(nd a, nd b){
return a._val > b._val;
}
};
public:
vector smallestRange(vector>& nums) {
int rows = nums.size();
// 使用一个优先队列来维护,注意优先队列小顶堆的构造方法
priority_queue, cmp> pq;
int max_val = INT_MIN;
// 先将每一个序列的第一位放入优先队列
for(int i=0;i({ret_start, ret_end});
}
};
找工作路漫漫,但求不忘初心,回首对得起走过的路。
代码地址:[luuuyi/leetcode-contest]