LeetCode Weekly Contest 19

1.504. Base 7

水题,直接写。但是我错了一次,忘了处理0的情况。 没有考虑边界条件。写完代码,一般需要自己想几个边界测试用例进行测试。

 1 class Solution {
 2 public:
 3 string convertTo7(int num) {
 4     if(num == 0) return "0";
 5     int a = abs(num);
 6     string res;
 7     while(a) {
 8         int t = a % 7;
 9         a /= 7;
10         res += char(t + '0');
11     }
12     if(num < 0)
13         res += "-";
14     reverse(res.begin(), res.end());
15     return res;
16 
17 }
18 };
View Code

上面的abs好像没考虑最大的负数溢出问题,注意!题目数据范围小!

2. 513. Find Left Most Element

水题吧,记录一下,每一层的起始元素,返回最后一层的起始值。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12   int findLeftMostNode(TreeNode* root) {
13     queue<TreeNode*> q;
14     q.push(root);
15     int res = root->val;
16     while(!q.empty()) {
17         int sz = q.size();
18         res = q.front()->val;
19         while(sz--) {
20             TreeNode* t = q.front();
21             q.pop();
22             if(t->left) q.push(t->left);
23             if(t->right) q.push(t->right);
24         }
25     }
26     return res;
27 }
28 };
View Code

3. 515. Find Largest Element in Each Row

跟第二题一样,也算水题吧,每一层求解一下最大值。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12   vector<int> findValueMostElement(TreeNode* root) {
13     vector<int> res;
14     if(!root) return res;
15     queue<TreeNode*> q;
16     q.push(root);
17     while(!q.empty()) {
18         int sz = q.size();
19         int d = INT_MIN;
20         while(sz--) {
21             TreeNode* t = q.front();
22             q.pop();
23             d = max(d, t->val);
24             if(t->left) q.push(t->left);
25             if(t->right) q.push(t->right);
26         }
27         res.push_back(d);
28     }
29     return res;
30 }
31 };
View Code

4. 493. Reverse Pairs

原题,你一定做过求逆序对的题目,就跟这个一模一样。但是,我还是花了一些时间。依稀记得,这道题,我是原模原样见过,在上算法课的时候,老师讲divide and conquer的作业题,我记得我做错了,当时差不多搞懂了,现在又不会了!还是当初没搞懂啊!

一种解法是mergesort,在merge的时候,求解个数,求逆序对很容易计算,跟排序的循环一起,但是这道题目就不一样,需要单独的循环计算这个特别的逆序对。在开启一个循环计算,复杂对一样,只是增加了一些系数的时间。

另一种解法是树状数组,(当然,线段树也可以),按顺序插入一个数,记当前数为a[i],统计大于2*a[i]的元素的个数,然后插入a[i]. 插入和计数可以用树状数组高效的维护。需要注意(看的第一名大神的写法):树状数组的下标非负,这题数据有负数,还有数据范围很大,需要离散化处理,但是,又有二倍的数,不好处理,可以使用map,负数的下标加上一个base偏移来解决。 这题的数据很大,二倍的数据会溢出int,算是一个很大的坑吧! 题目做的多了,应该一眼就能看到这题的考点,数据溢出!看前面的神牛,就一次没有错!

贴上我写的代码,(写的不是很好,可以参考排名靠前大神们的代码):

mergesort:

 1 typedef long long ll;
 2 class Solution {
 3 public:
 4   int res;
 5  vector<int> b;
 6 void mg(vector<int> &a, int x, int mid, int y) {
 7     
 8    
 9     int i = x, j = mid + 1;
10     int p = x;
11     for (int k = 0; k < y - x + 1; k++) {
12         if(i > mid) {
13             b[p] = a[j];
14             j++; p++;
15             continue;
16         }
17         if(j > y) {
18             b[p] = a[i];
19             p++;
20             i++;
21             continue;
22         }
23         if(a[i] <= a[j]) {
24             b[p] = a[i];
25             i++; p++;
26         } else {
27             b[p] = a[j];
28             p++; j++;
29         }
30     }
31     i = x; j = mid + 1;
32     for (int k = 0; k < y - x + 1; k++) {
33         if(i > mid) break;
34         if(j > y) break;
35         ll td = a[j];
36         if(a[i] > 2 * td) {
37             res += (mid + 1 - i);
38             j++;
39         } else i++;
40     }
41     for (int k = x; k <= y; k++)
42         a[k] = b[k];
43 }
44 void mergesort(vector<int> &a, int left, int right) {
45     if(left >= right) return;
46     int mid = (left + right) / 2;
47     mergesort(a, left, mid);
48     mergesort(a, mid + 1, right);
49     mg(a, left, mid, right);
50 }
51 int reversePairs(vector<int>& nums) {
52     res = 0;
53     int n = nums.size();
54     if(n < 2) return res;
55     b = nums;
56     mergesort(nums, 0, n - 1);
57     return res;
58 }
View Code

树状数组:

 1 typedef long long ll;
 2 class Solution {
 3 public:
 4   int res;
 5 map<ll, int> ma;
 6 ll base = 1ll << 34;
 7 ll lowbit(ll x) {
 8     return x & -x;
 9 }
10 void add(ll x) {
11     x += base;
12     while(x <= 1ll << 36) {
13         ma[x]++;
14         x += lowbit(x);
15     }
16 }
17 int ask(ll x) {
18     x += base;
19     int res = 0;
20     while(x) {
21         res += ma[x];
22         x -= lowbit(x);
23     }
24     return res;
25 }
26 int reversePairs2(vector<int>& nums) {
27     res = 0;
28     int n = nums.size();
29     if(n < 2) return res;
30     ma.clear();
31     for (int i = n - 1; i >= 0; i--) {
32         res += ask(nums[i] - 1ll);
33         add(2ll * nums[i]);
34     }
35     return res;
36 }
View Code

 

转载于:https://www.cnblogs.com/y119777/p/6391317.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值