一刷leetcode——数组
118. Pascal's Triangle
题意:输出杨辉三角前n行
我的思路:大水题
我的代码:
class Solution { public: vector<vector<int>> generate(int numRows) { vector<vector<int>> ans; if (numRows == 0) return ans; for (int i = 1; i <= numRows; i++) { vector<int> tmp; for (int j = 1; j <= i; j++) { if (j == 1 || j == i) { tmp.push_back(1); } else { tmp.push_back(ans[i-2][j-2]+ans[i-2][j-1]); } } ans.push_back(tmp); } return ans; } };
119. Pascal's Triangle II
题意:输出杨辉三角第k行,k从0起
我的思路:大水题
我的代码:
class Solution { public: vector<int> getRow(int rowIndex) { vector<int> ans(rowIndex+1); for (int i = 0; i <= rowIndex; i++) for (int j = i; j >= 0; j--) { if (j == 0 || j == i) ans[j] = 1; else ans[j] = ans[j-1]+ans[j]; } return ans; } };
122. Best Time to Buy and Sell Stock II
题意:给定每天股票价格,输出买入卖出的最大收益,注意最多有一只股票在手
我的思路:题虽然水,但是并没有一下想到最好的方法,只需要在答案中加入后一天比前一天高时的差价即可
我的代码:
class Solution { public: int maxProfit(vector<int>& prices) { if (prices.empty()) return 0; int minn = prices[0], maxn = prices[0], ans = 0; for (int i = 1; i < prices.size(); i++) { if (prices[i] < prices[i-1]) { ans += maxn-minn; minn = maxn = prices[i]; } if (prices[i] > prices[i-1]) maxn = prices[i]; } ans += maxn-minn; return ans; } };
九章最优解:
class Solution { public: /** * @param prices: Given an integer array * @return: Maximum profit */ int maxProfit(vector<int> &prices) { // write your code here int total=0; if(!prices.empty()) { for(int i=0; i<prices.size()-1; i++) { if(prices[i+1]>prices[i])total+=prices[i+1]-prices[i]; } } return total; } };
125. Valid Palindrome
题意:判断一个字符串是否是回文的(只看字母或数字)
我的思路:首尾两个指针扫,水题
我的代码:
class Solution { public: bool isPalindrome(string s) { if (s.size() == 0) return 1; int l = 0, r = s.size()-1; while (l < r) { if (!isalnum(s[l])) { l++; continue; } if (!isalnum(s[r])) { r--; continue; } if (s[l] >= 'A' && s[l] <= 'Z') s[l] += 32; if (s[r] >= 'A' && s[r] <= 'Z') s[r] += 32; if (s[l] != s[r]) return 0; l++; r--; } return 1; } };
九章最优解:思路一样,自己语法太差
class Solution { public: bool isPalindrome(string s) { transform(s.begin(), s.end(), s.begin(), ::tolower); auto left = s.begin(), right = prev(s.end()); while (left < right) { if (!::isalnum(*left)) ++left; else if (!::isalnum(*right)) --right; else if (*left != *right) return false; else{ left++, right--; } } return true; } };
127. Word Ladder
题意:给定一个字典和起始、结束单词,输出从起始到结束的单词链有多长(每次只能改变一个字母)
我的思路:bfs
我的代码:
class Solution { public: int ladderLength(string beginWord, string endWord, vector<string>& wordList) { queue<string> q; map<string, int> m; for (int i = 0; i < wordList.size(); i++) m[wordList[i]] = 1; q.push(beginWord); int ans = 1; while (!q.empty()) { int n = q.size(); ans++; for (int i = 0; i < n; i++) { string s = q.front(); q.pop(); for (int j = 0; j < s.size(); j++) { string tmp = s; for (int k = 0; k < 26; k++) { tmp[j] = 'a'+k; if (tmp != s && m.find(tmp) != m.end() && m[tmp] == 1) { if (tmp == endWord) return ans; m[tmp]++; q.push(tmp); } } } } } return 0; } };
130. Surrounded Regions
题意:简单dfs
我的代码:
class Solution { public: int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; void dfs(vector<vector<char>>& board, int x, int y, vector<vector<int>>& flag){ flag[x][y] = 1; int m = board.size(), n = board[0].size(); for (int i = 0; i < 4; i++) { int xx = x+dir[i][0], yy = y+dir[i][1]; if (xx >= 0 && xx < m && yy >= 0 && yy < n && board[xx][yy] == 'O' && flag[xx][yy] == 0) dfs(board, xx, yy, flag); } } void solve(vector<vector<char>>& board) { if (board.size() == 0) return; int m = board.size(), n = board[0].size(); vector<vector<int> > flag(m, vector<int>(n, 0)); for (int i = 0; i < n; i++) { if (board[0][i] == 'O' && flag[0][i] == 0) dfs(board, 0, i, flag); if (board[m-1][i] == 'O' && flag[m-1][i] == 0) dfs(board, m-1, i, flag); } for (int i = 0; i < m; i++) { if (board[i][0] == 'O' && flag[i][0] == 0) dfs(board, i, 0, flag); if (board[i][n-1] == 'O' && flag[i][n-1] == 0) dfs(board, i, n-1, flag); } for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) if (board[i][j] == 'O' && flag[i][j] == 0) board[i][j] = 'X'; } };
131. Palindrome Partitioning
题意:将字符串分解成回文串的连接
我的思路:基本dfs
我的代码:
class Solution { public: vector<vector<string>> ans; bool ispalin(string s) { int i = 0, j = s.size()-1; while (i < j && s[i] == s[j]) i++, j--; return i >= j; } void dfs(string s, vector<string> tmp) { for (int i = 1; i <= s.size(); i++) { if (ispalin(s.substr(0, i))) { tmp.push_back(s.substr(0, i)); if (i < s.size()) { dfs(s.substr(i, s.size()-i), tmp); tmp.pop_back(); } else { ans.push_back(tmp); } } } } vector<vector<string>> partition(string s) { vector<string> tmp; dfs(s, tmp); return ans; } };
134. Gas Station
题意: 环形路上有n个油站,可以加油gas[i],走到下个油站耗油cost[i],问开一辆无限加油的车从哪个站走能走完全程,无解输出-1.注:最多一个解
我的思路:这个思路也是看的,只需遍历一遍站点,从站i往后加gas减cost记为num,若num小于0了,则不可能在0~i之间的站点走完全程(想一想,不难),这时把num清零重计,从i+1看起即可,若最后所有的num之和为负,则无解
我的代码:
class Solution { public: int canCompleteCircuit(vector<int>& gas, vector<int>& cost) { int num = 0, ans = 0, cnt = 0; for (int i = 0; i < gas.size(); i++) { num += gas[i]-cost[i]; if (num < 0) { cnt += num; ans = i+1; num = 0; } } return cnt+num < 0 ? -1 : ans; } };
九章最优解:看不懂,不过没上边好
class Solution { public: /** * @param gas: a vector of integers * @param cost: a vector of integers * @return: an integer */ int canCompleteCircuit(vector<int> &gas, vector<int> &cost) { auto const L = gas.size(); auto sum = accumulate(gas.begin(), gas.end(), 0) - accumulate(cost.begin(), cost.end(), 0); if (sum < 0) return -1; int a = 0; for (int i = 0; i < L; i++) { if (gas[i] - cost[i] >= 0) { a = i; break; } } int b = a; auto diff = [&gas, &cost](int x) {return gas[x] - cost[x];}; int gas_remain = diff(a); while ((b + 1) % L != a) { if (diff((b + 1) % L) + gas_remain >= 0) { b = (b + 1) % L; gas_remain += diff(b); } else if (diff((L + a - 1) % L) + gas_remain >= 0) { a = (L + a - 1) % L; gas_remain += diff(a); } else { return -1; } } return a; } };
135. Candy
题意:给定n个人每人一个等级值,分糖果,每人至少一个,等级高的人分得的糖果比他两侧的等级低的要多,等级相同的多少无限制,问最少需要多少糖果
我的思路:开一个n的数组表示每个人分的糖果数,初始化为1,从左往右扫,遇到升序则i处的糖果数是i-1处加1,之后从右往左扫,若遇升序且糖果数不是升序,则i处糖果数改为i+1处糖果数+1
我的代码:
class Solution { public: int candy(vector<int>& ratings) { if (ratings.size() == 0) return 0; int n = ratings.size(), ans = 0; vector<int> num(n); for (int i = 0; i < n; i++) num[i] = 1; for (int i = 1; i < n; i++) if (ratings[i] > ratings[i-1]) num[i] = num[i-1]+1; for (int i = n-2; i >= 0; i--) if (ratings[i] > ratings[i+1] && num[i] <= num[i+1]) num[i] = num[i+1]+1; for (int i = 0; i < n; i++) ans += num[i]; return ans; } };
九章最优解:一样
class Solution { public: int candy(vector<int>& ratings) { vector<int> candies(ratings.size()); candies[0] = 1; for (int i = 1; i < ratings.size(); i++) { if (ratings[i] > ratings[i - 1]) { candies[i] = candies[i - 1] + 1; } else { candies[i] = 1; } } for (int i = ratings.size() - 2; i >= 0; i--) { if (ratings[i] > ratings[i + 1]) { candies[i] = max(candies[i], candies[i + 1] + 1); } } int sum = 0; for (int i = 0; i < candies.size(); i++) { sum += candies[i]; } return sum; } };
136. Single Number
题意:一个数组中只有一个数字只出现一遍,其余都是两边,找到这个数字
我的思路:水题,异或
我的代码:
class Solution { public: int singleNumber(vector<int>& nums) { int ans = 0; for (int i = 0; i < nums.size(); i++) ans ^= nums[i]; return ans; } };
九章最优解:一样
class Solution { public: /** * @param A : an integer array * return : a integer */ int singleNumber(vector<int> &A) { int x; for (int i = 0; i < A.size(); i++) { x ^= A[i]; } return x; } };
137. Single Number II
题意:一个数组中只有一个数出现了1次,其他都是三次,找出这个数
我的思路:借鉴的别人的,见代码注释
class Solution { public: int singleNumber(vector<int>& nums) { int ones = 0, twos = 0; for (int i = 0; i < nums.size(); i++) { ones = (ones^nums[i]) & ~twos; //当nums[i]第一次出现时,twos中相应的位是0,它对前边的异或结果没有影响,故ones记录了刚出现一次的数字 //当nums[i]第二次出现时,ones再次异或同一个数消除了这个数的影响,twos中也没这个数没有影响 //当nums[i]第三次出现时,因为出现两次时twos有记录,因此& ~twos会将出现三次的数字的位置0,故nums[i]中只有出现一次的数 twos = (twos^nums[i]) & ~ones; //当nums[i]第一次出现时,twos异或了它但是被ones消除了,因为后边的操作是把ones中是1的位置0,故出现一次的数不会记录 //当nums[i]第二次出现时,twos会保留这个数,因为ons中没有这个数的影响 //当nums[i]第三次出现时,twos实际上是第二次异或这个数,所以出现三次的数被从twos中消除 } return ones; } };
九章最优解:思路见代码注释
class Solution { public: int singleNumber(int A[], int n) { int one=0; int two=0; int i,j,k; for(i=0; i<n; i++) { two = two |(one&A[i]); one = one^A[i]; int three = two&one; //将出现三次的数清零 two = two^three; one = one^three; } return one|two; } };
146. LRU Cache
题意:看题吧,主要是要求每个操作的时间复杂度都是O(1)
思路:双向链表加hash
我的代码:
class LRUCache { private: list<int> used; map<int, pair<int, list<int>::iterator> > cache; int cap; void touch(map<int, pair<int, list<int>::iterator> >::iterator it) { int k = it->first; used.erase(it->second.second); used.push_front(k); it->second.second = used.begin(); } public: LRUCache(int capacity) : cap(capacity){} int get(int key) { auto it = cache.find(key); if (it == cache.end()) return -1; touch(it); return it->second.first; } void put(int key, int value) { auto it = cache.find(key); if (it != cache.end()) touch(it); else { if (cap == cache.size()) { cache.erase(used.back()); used.pop_back(); } used.push_front(key); } cache[key] = {value, used.begin()}; } };
260. Single Number III
题意:数组里只有两个数只出现了一次,其他都两次,找出这两个数
我的思路:(其实是看的别人的T.T)把所有数字全异或得到的结果是两个所求数字的异或,这个数为二进制1的位置(我这里借鉴了树状数组的一个位操作)都是两个数不同的位,根据这个位将所有数字分为两组分别异或即可得到两个数。
我的代码:
class Solution { public: vector<int> singleNumber(vector<int>& nums) { int x = 0; vector<int> ans(2, 0); for (int i = 0; i < nums.size(); i++) x ^= nums[i]; x = log(x&-x)/log(2); ///从右数第一个1的位置,灵感来自树状数组 for (int i = 0; i < nums.size(); i++) { if (nums[i] & (1<<x)) ans[1] ^= nums[i]; else ans[0] ^= nums[i]; } return ans; } };
九章最优解:思路一样,找1位置我的好
class Solution { public: /** * @param A : An integer array * @return : two integers */ vector<int> singleNumberIII(vector<int> &A) { // write your code here int x = 0, len = A.size(), pos; for (int i = 0; i < len; ++i) x ^= A[i]; for (int i = 0; i < 32; ++i) if (x & (1 << i)) { pos = i; break; } vector<int> results(2); for (int i = 0; i < len; ++i) if (A[i] & (1 << pos)) results[0] ^= A[i]; else results[1] ^= A[i]; return results; } };
150. Evaluate Reverse Polish Notation
题意:通过后缀表达式计算
我的思路:根据后缀表达式的定义只需要一个栈即可,注意些细节没什么难度
我的代码:
class Solution { public: int evalRPN(vector<string>& tokens) { stack<int> gg; for (int i = 0; i < tokens.size(); i++) { if (tokens[i][0] >= '0' && tokens[i][0] <= '9'|| tokens[i][0] == '-' && tokens[i].size() > 1) { int tmp = 0; for (int j = tokens[i][0] == '-' ? 1 : 0; j < tokens[i].size(); j++) tmp = tmp*10+tokens[i][j]-'0'; if (tokens[i][0] == '-') tmp = -tmp; gg.push(tmp); } else { int a = gg.top(); gg.pop(); int b = gg.top(); gg.pop(); switch(tokens[i][0]) { case '+': gg.push(b+a); break; case '-': gg.push(b-a); break; case '*': gg.push(b*a); break; case '/': if (a == 0) return 0; gg.push(b/a); break; } } } return gg.top(); } };
九章最优解:对语法的掌握比我好很多
class Solution { public: int evalRPN(vector<string> &tokens) { int x, y; auto token = tokens.back(); tokens.pop_back(); if (is_operator(token)) { y = evalRPN(tokens); x = evalRPN(tokens); if (token[0] == '+') x += y; else if (token[0] == '-') x -= y; else if (token[0] == '*') x *= y; else x /= y; } else { size_t i; x = stoi(token, &i); } return x; } private: bool is_operator(const string &op) { return op.size() == 1 && string("+-*/").find(op) != string::npos; } };
151. Reverse Words in a String
题意:字符串翻转,没啥意思
我的代码:
class Solution { public: void reverseWords(string &s) { if (s.size() == 0) return; while (s[0] == ' ') s.erase(s.begin()); while (s[s.size()-1] == ' ') s.erase(s.end()-1); for (int i = 1; i < s.size(); i++) { if (s[i] == ' ' && s[i] == s[i-1]) { s.erase(s.begin()+i); i--; } } int i = 0, j = 0, n = s.size(); while (j < n) { if (s[j] == ' ') { reverse(s.begin()+i, s.begin()+j); i = j+1; } j++; } reverse(s.begin()+i, s.end()); reverse(s.begin(), s.end()); } };
153. Find Minimum in Rotated Sorted Array
题意:找到折翻过的有序数组的最小值
我的思路:二分1A
我的代码:
class Solution { public: int findMin(vector<int>& nums) { int l = 0, r = nums.size()-1; while (l+1 < r) { int mid = (l+r)/2; if (nums[mid] > nums[r]) l = mid; else r = mid; } return min(nums[l], nums[r]); } };
九章最优解:一样
class Solution { public: /** * @param nums: a rotated sorted array * @return: the minimum number in the array */ int findMin(vector<int> &nums) { // write your code here int left = 0, right = nums.size() - 1; while (nums[left] > nums[right]) { int mid = (left + right) / 2; if (nums[mid] >= nums[left] && nums[mid] > nums[right]) left = mid+1; else right = mid; } return nums[left]; } };
154. Find Minimum in Rotated Sorted Array II
题意:折翻过的有序数组中有重复数字时,找到其最小值
我的思路:二分,nums[l]与nums[r]相等时,l右移或r左移即可
我的代码:
class Solution { public: int findMin(vector<int>& nums) { int l = 0, r = nums.size()-1; while (l+1 < r) { if (nums[l] == nums[r]) { l++; continue; } int mid = (l+r)/2; if (nums[mid] > nums[r]) l = mid; else r = mid; } return min(nums[l], nums[r]); } };
九章最优解:也是二分,处理方式不太一样
class Solution { public: /** * @param num: the rotated sorted array * @return: the minimum number in the array */ int findMin(vector<int> &num) { // write your code here int lo = 0; int hi = num.size()-1; while(lo<hi){ int mid = lo + (hi - lo)/2; if(num[mid]>num[hi]){ lo = mid+1; }else if(num[mid]<num[hi]){ hi = mid; }else{ hi--; } } return num[lo]; } };
155. Min Stack
题意:设计一个栈能够实现push, pop, top, getMin(返回最小值)操作
我的思路:一个vector或者栈,一个值minn保存当前最小值,每次入栈入两个数:x和当前(包括x)最小值minn
我的代码:
class MinStack { public: vector<int> a; int minn; /** initialize your data structure here. */ MinStack() { minn = 0x7fffffff; } void push(int x) { a.push_back(x); minn = min(minn, x); a.push_back(minn); } void pop() { a.pop_back(); a.pop_back(); minn = a.size() == 0 ? 0x7fffffff : a[a.size()-1]; } int top() { return a[a.size()-2]; } int getMin() { return a[a.size()-1]; } };
九章最优解:两个栈,一个存入栈的数,一个存最小值,但是最小值不是每次都入,改变时才入站出栈,比我的好
class MinStack { public: stack<int> stk, minstk; void push(int number) { stk.push(number); if (minstk.empty() or number <= minstk.top()) { minstk.push(number); } } int pop() { int top = stk.top(); stk.pop(); if (top == minstk.top()) { minstk.pop(); } return top; } int min() { return minstk.top(); } };
162. Find Peak Element
题意:找到数组的极值点,保证两端最低,多极值点时任意一个均可
我的思路:三分
我的代码:虽然a了,但是没太想明白多极值点的时候能不能行
class Solution { public: int findPeakElement(vector<int>& nums) { int l = 0, h = nums.size()-1; while (h > l+1) { int mid1 = (2*l+h)/3, mid2 = (l+2*h)/3; if (nums[mid1] > nums[mid2]) h = mid2; else l = mid1+1; } return nums[l] > nums[h] ? l : h; } };
九章最优解:二分,当mid比两边高时输出
class Solution { public: /** * @param A: An integers array. * @return: return any of peek positions. */ int findPeak(vector<int> A) { int l = 1, r = A.size(); while (l <= r) { int mid = (l + r) / 2; if (A[mid] > A[mid-1] && A[mid] > A[mid+1]) return mid; if (A[mid] > A[mid-1]) l = mid + 1; else r = mid - 1; } return -1; } };
164. Maximum Gap
题意:输出一个无序数组排序后相邻元素的最大差值
我的思路:第一次桶排序,思路可见solution第一个
我的代码:
class Solution { public: int maximumGap(vector<int>& nums) { if (nums.size() < 2) return 0; int n = nums.size(), maxn = 0, minn = 0x7fffffff; for (int i = 0; i < n; i++) { maxn = max(maxn, nums[i]); minn = min(minn, nums[i]); } int gap = ceil((double)(maxn-minn)/(n-1)); if (gap == 0) return 0; vector<vector<int> > bucket(n-1, vector<int>(2, 0)); //0最小值,1最大值 for (int i = 0; i < n-1; i++) bucket[i][0] = 0x7fffffff; for (int i = 0; i < n; i++) if (nums[i] != minn && nums[i] != maxn) { int k = (nums[i]-minn)/gap; bucket[k][0] = min(bucket[k][0], nums[i]); bucket[k][1] = max(bucket[k][1], nums[i]); } int ans = gap, pre = minn; for (int i = 0; i < n-1; i++) { if (bucket[i][0] == 0x7fffffff) continue; ans = max(bucket[i][0]-pre, ans); pre = bucket[i][1]; } return max(ans, maxn-pre); } };
165. Compare Version Numbers
题意:比较版本号
我的思路:常规字符串,很无聊的题
我的代码:
class Solution { public: int compareVersion(string version1, string version2) { version1 += '.'; version2 += '.'; int i = 0, j = 0; while (i < version1.size() || j < version2.size()) { int num1 = 0, num2 = 0; while (i < version1.size() && version1[i] != '.') num1 = num1*10+version1[i++]-'0'; i++; while (j < version2.size() && version2[j] != '.') num2 = num2*10+version2[j++]-'0'; j++; if (num1 != num2) return num1 > num2 ? 1 : -1; } return 0; } };
166. Fraction to Recurring Decimal
题意:给定分子分母,输出小数形式,循环小数写成循环节
我的思路:哈希余数找循环节
我的代码:
class Solution { public: string fractionToDecimal(int numerator, int denominator) { long long a = numerator, b = denominator; string qian, hou, fuhao; vector<long long> mod; long long yu, loc; if (a*b < 0) fuhao = "-"; a = abs(a); b = abs(b); qian = to_string(a/b); yu = a%b; while (yu) { mod.push_back(yu); hou += to_string(yu*10/b); if (yu*10/b == 0) { yu *= 10; continue; } yu = yu*10%b; if (find(mod.begin(), mod.end(), yu) != mod.end()) { loc = find(mod.begin(), mod.end(), yu)-mod.begin(); break; } } if (hou.size() == 0) return fuhao+qian; if (yu == 0) return fuhao+qian+'.'+hou; return fuhao+qian+'.'+hou.substr(0, loc)+'('+hou.substr(loc, hou.size()-loc)+')'; } };
168. Excel Sheet Column Title
easy题不会做,傻逼
169. Majority Element
题意:输出数组中出现次数大于[n/2]的元素
我的思路:排序后处于中间的元素必然是所求,虽然写起来简洁,但是时间复杂度一般
我的代码:
class Solution { public: int majorityElement(vector<int>& nums) { sort(nums.begin(), nums.end()); return nums[nums.size()/2]; } };
九章最优解:很巧妙,即一个个数count和一个候选元素a,当count为0时,候选元素记为当前元素,之后当nums[i]等于a时,count++,否则count--
class Solution { public: int majorityNumber(vector<int> nums) { int candidate, count = 0; for (int i = 0; i < nums.size(); i++) { if (count == 0) { candidate = nums[i]; count ++; } else { if (candidate == nums[i]) { count ++; } else { count --; } } } return candidate; } };
171. Excel Sheet Column Number
题意:大水题,过
172. Factorial Trailing Zeroes
题意:输出n!后边有多少个0
我的思路:水题,数5
我的代码:
class Solution { public: int trailingZeroes(int n) { int a[13] = {5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625, 1220703125}, ans = 0; for (int i = 0; i < 13; i++) ans += n/a[i]; return ans; } };
179. Largest Number
题意:给定一组数字,输出他们相连能够组成的最大数字
我的思路:写一个排序函数即可
我的代码:
class Solution { public: static bool cmp(const int& a, const int& b) { string aa = to_string(a), bb = to_string(b); string s1 = aa+bb, s2 = bb+aa; for (int i = 0; i < s1.length(); i++) if (s1[i] != s2[i]) return s1[i] > s2[i]; return 0; } string largestNumber(vector<int>& nums) { string ans; sort(nums.begin(), nums.end(), cmp); for (int i = 0; i < nums.size(); i++) ans += to_string(nums[i]); int i = 0; while (i < ans.size()-1 && ans[i] == '0') i++; return ans.substr(i, ans.size()-i); } };
187. Repeated DNA Sequences
题意:找出一个长DNA序列里长度为10并且重复出现的序列
我的思路:对长度为10的串hash,输出重复出现的
我的代码:
class Solution { public: vector<string> findRepeatedDnaSequences(string s) { vector<string> ans; if (s.size() <= 10) return ans; unordered_map<string, int> hash; for (int i = 0; i < s.size()-9; i++) { string tmp = s.substr(i, 10); if (hash.find(tmp) != hash.end()) { if (hash[tmp] == 1) ans.push_back(tmp); hash[tmp]++; } else { hash[tmp] = 1; } } return ans; } };
九章最优解:位运算,将不同的碱基映射为不同的位值,记为一个整数,对这个整数hash可以省很多内存,题解:http://blog.csdn.net/ljiabin/article/details/44488619,九章最优解实际上是映射为两个位的不同值
public class Solution { public int encode(String s) { int sum = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == 'A') { sum = sum * 4; } else if (s.charAt(i) == 'C') { sum = sum * 4 + 1; } else if (s.charAt(i) == 'G') { sum = sum * 4 + 2; } else { sum = sum * 4 + 3; } } return sum; } public List<String> findRepeatedDnaSequences(String s) { HashSet<Integer> hash = new HashSet<Integer>(); HashSet<String> dna = new HashSet<String>(); for (int i = 9; i < s.length(); i++) { String subString = s.substring(i - 9, i + 1); int encoded = encode(subString); if (hash.contains(encoded)) { dna.add(subString); } else { hash.add(encoded); } } List<String> result = new ArrayList<String>(); for (String d: dna) { result.add(d); } return result; } }
190. Reverse Bits
题意:输出一个32位无符号数所有位反转的数字
我的思路:比较笨,32位一位一位来
我的代码:
class Solution { public: uint32_t reverseBits(uint32_t n) { uint32_t ans = 0; for (int i = 0; i < 32; i++) { ans <<= 1; ans |= n&1; n >>= 1; } return ans; } };
九章最优解:一样
public class Solution { // you need treat n as an unsigned value public int reverseBits(int n) { int reversed = 0; for (int i = 0; i < 32; i++) { reversed = (reversed << 1) | (n & 1); n = (n >> 1); } return reversed; } }
191. Number of 1 Bits
题意:输出一个数字的汉明重,即二进制1的个数
我的思路:右移判1
我的代码:
class Solution { public: int hammingWeight(uint32_t n) { int num = 0; for (int i = 0; i < 32; i++) { num += n&1; n >>= 1; } return num; } };
九章最优解:n&(n-1)的妙用,可以把最后的1(不一定在最后一位)变成0
public class Solution { // you need to treat n as an unsigned value public int hammingWeight(int n) { if (n == 0) { return 0; } int count = 1; while ((n & (n - 1)) != 0) { n &= n-1; count++; } return count; } }
200. Number of Islands
题意:给定一个二维数组,1表示陆地,0表示水,1上下左右相连,问有几座小岛
我的思路:dfs水题
我的代码:
class Solution { public: int ans, dir[5][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; void dfs(vector<vector<char>>& grid, int x, int y) { grid[x][y] = '0'; for (int i = 0; i < 4; i++) { int xx = x+dir[i][0], yy = y+dir[i][1]; if (xx >= 0 && xx < grid.size() && yy >= 0 && yy < grid[0].size() && grid[xx][yy] == '1') dfs(grid, xx, yy); } } int numIslands(vector<vector<char>>& grid) { if (grid.size() == 0) return 0; for (int i = 0; i < grid.size(); i++) for (int j = 0; j < grid[0].size(); j++) if (grid[i][j] == '1') { ans++; dfs(grid, i, j); } return ans; } };
九章最优解:思路一样
class Solution { public: /** * @param grid a boolean 2D matrix * @return an integer */ void dfs(vector<vector<bool>> &grid, int x, int y) { if (x < 0 || x >= grid.size()) return; if (y < 0 || y >= grid[0].size()) return; if (!grid[x][y]) return; grid[x][y] = false; dfs(grid, x + 1, y); dfs(grid, x - 1, y); dfs(grid, x, y + 1); dfs(grid, x, y - 1); } int numIslands(vector<vector<bool>>& grid) { // Write your code here if (grid.empty() || grid[0].empty()) return 0; int N = grid.size(), M = grid[0].size(); int cnt = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < M; ++j) { if (grid[i][j]) { dfs(grid, i, j); ++cnt; } } } return cnt; } };
201. Bitwise AND of Numbers Range
题意:输出m~n之间所有数字的按位与
我的思路:就是输出m与n的左边相同部分
我的代码:
class Solution { public: int rangeBitwiseAnd(int m, int n) { int gg = 0x7fffffff; while ((m & gg) != (n & gg)) gg <<= 1; return m & gg; } };
solution解法:
class Solution { public: int rangeBitwiseAnd(int m, int n) { int cnt = 0; while (m != n){ m >>= 1; n >>= 1; cnt++; } return m << cnt; } };
202. Happy Number
题意:判一个数是不是happy number:各位平方和循环求是否会归于1
solution一个很巧妙的思路:2-6中没有HN,当n进行各位平方求和小于等于6时退出,但是为什么一定会到7以内呢?
class Solution { public: map<int, int> hehe; bool isHappy(int n) { while (n > 6) { int tmp = 0; while (n > 0) { tmp += (n%10)*(n%10); n /= 10; } n = tmp; } return n == 1; } };
九章最优解:通过map判数字的循环,重复数字不是1时结果为否
class Solution { public: /** * @param n an integer * @return true if this is a happy number or false */ bool isHappy(int n) { // Write your code here if (n < 1) return false; if (n == 1) return true; unordered_set<int> showedNums; showedNums.insert(n); while (true) { int s = 0; while (n) { s += (n % 10) * (n % 10); n = n / 10; } if (s == 1) return true; else if (showedNums.find(s) != showedNums.end()) return false; n = s; showedNums.insert(s); } } };
204. Count Primes
题意:给定n,输出[1, ni1)的素数个数
我的思路:筛法找素数改改
我的代码:
class Solution { public: int countPrimes(int n) { int ans = n-2; vector<int> flag(n, 0); for (int i = 2; i <= sqrt(n); i++) { if (!flag[i]) { for (int j = 2; j*i < n; j++) { if (!flag[j*i]) { flag[j*i] = 1; ans--; } } } } return max(0, ans); } };
别人解法:
int countPrimes(int n) { if (n<=2) return 0; vector<bool> passed(n, false); int sum = 1; int upper = sqrt(n); for (int i=3; i<n; i+=2) { if (!passed[i]) { sum++; //avoid overflow if (i>upper) continue; for (int j=i*i; j<n; j+=i) { passed[j] = true; } } } return sum; }
205. Isomorphic Strings
题意:判断s串能否由t串这样得到:t串的某个字母代表s串中的某个字母,替换后得到s串,但不能t串中两个字母都对应s串中的一个
我的思路:哈希,既要记录s串的某字母由t串的哪个得到,又要记录t串的某字母是否已经有对应的字母
我的代码:
class Solution { public: bool isIsomorphic(string s, string t) { if (s.size() != t.size()) return 0; unordered_map<char, char> hash; vector<bool> flag(256, 0); for (int i = 0; i < s.size(); i++) { if (hash.find(s[i]) != hash.end() && hash[s[i]] != t[i]) return 0; else if (hash.find(s[i]) == hash.end()) { if (!flag[t[i]]) { hash[s[i]] = t[i]; flag[t[i]] = 1; } else { return 0; } } } return 1; } };
solution解法:开两个数组分别记录s和t串对应对方的位置,不同时返回0
class Solution { public: bool isIsomorphic(string s, string t) { int m1[256] = {0}, m2[256] = {0}, n = s.size(); for (int i = 0; i < n; ++i) { if (m1[s[i]] != m2[t[i]]) return false; m1[s[i]] = i + 1; m2[t[i]] = i + 1; } return true; } };
209. Minimum Size Subarray Sum
题意:给定一个数组和s,求和不小于s的最小子串长度
我的思路:将数组改为nums[i]前边元素到i的和,最前边加个0元素,二分求解,类似最大值最小化
我的代码:
class Solution { public: bool judge(vector<int> &sum, int m, int s) { for (int i = 0; i < sum.size()-m; i++) if (sum[i+m]-sum[i] >= s) return 1; return 0; } int minSubArrayLen(int s, vector<int>& nums) { nums.insert(nums.begin(), 0); for (int i = 1; i < nums.size(); i++) nums[i] += nums[i-1]; if (nums[nums.size()-1] < s) return 0; int l = 1, r = nums.size(); while (l+1 < r) { int mid = (l+r)/2; if (judge(nums, mid, s)) r = mid; else l = mid; } return judge(nums, l, s) ? l : r; } };
九章最优解:双指针,很巧妙
class Solution { public: /** * @param nums: a vector of integers * @param s: an integer * @return: an integer representing the minimum size of subarray */ int minimumSize(vector<int> &nums, int s) { // write your code here int n = nums.size(); if (n==0) return -1; int left = 0, right = 0, total = 0, ans = n+1; while (right<n) { while (right<n && total<s) total += nums[right++]; if (total<s) break; while (left<right && total>=s) total -= nums[left++]; ans = min(ans, right-left+1); } if (ans==n+1) return -1; else return ans; } };
216. Combination Sum III
题意:给定k和n,给出k个1~9组成的和为n的组合,数字不重复使用
我的思路:dfs水题
我的代码:
class Solution { public: void dfs(vector<vector<int> > &ans, vector<int> tmp, int sum, int k, int n, vector<int> flag, int j) { if (tmp.size() == k && sum == n) ans.push_back(tmp); if (tmp.size() >= k) return; for (int i = j+1; i <= 9; i++) { if (!flag[i]) { tmp.push_back(i); flag[i] = 1; dfs(ans, tmp, sum+i, k, n, flag, i); tmp.pop_back(); flag[i] = 0; } } } vector<vector<int>> combinationSum3(int k, int n) { vector<vector<int> > ans; vector<int> tmp, flag(10, 0); dfs(ans, tmp, 0, k, n, flag, 0); return ans; } };
215. Kth Largest Element in an Array
题意:输出数组排序后第k大的数
我的思路:最朴素(垃圾)的排序输出
我的代码:
class Solution { public: int findKthLargest(vector<int>& nums, int k) { sort(nums.begin(), nums.end()); return nums[nums.size()-k]; } };
solution解法:
(1)O(N lg N) running time + O(1) memory.排序输出
(2)O(N lg K) running time + O(K) memory.将元素放入优先队列中,队列长度达到k时弹出最小的(即使队列长度始终为k),最后输出队尾元素
public int findKthLargest(int[] nums, int k) { final PriorityQueue<Integer> pq = new PriorityQueue<>(); for(int val : nums) { pq.offer(val); if(pq.size() > k) { pq.poll(); } } return pq.peek(); }
(3)O(N) best case / O(N^2) worst case running time + O(1) memory.类似于快排中的分治方法
public int findKthLargest(int[] nums, int k) { k = nums.length - k; int lo = 0; int hi = nums.length - 1; while (lo < hi) { final int j = partition(nums, lo, hi); if(j < k) { lo = j + 1; } else if (j > k) { hi = j - 1; } else { break; } } return nums[k]; } private int partition(int[] a, int lo, int hi) { int i = lo; int j = hi + 1; while(true) { while(i < hi && less(a[++i], a[lo])); while(j > lo && less(a[lo], a[--j])); if(i >= j) { break; } exch(a, i, j); } exch(a, lo, j); return j; } private void exch(int[] a, int i, int j) { final int tmp = a[i]; a[i] = a[j]; a[j] = tmp; } private boolean less(int v, int w) { return v < w; }
(4)O(N) guaranteed running time + O(1) space.将上一个解法加一步,在最开始将数组随机排列
public int findKthLargest(int[] nums, int k) { shuffle(nums); k = nums.length - k; int lo = 0; int hi = nums.length - 1; while (lo < hi) { final int j = partition(nums, lo, hi); if(j < k) { lo = j + 1; } else if (j > k) { hi = j - 1; } else { break; } } return nums[k]; } private void shuffle(int a[]) { final Random random = new Random(); for(int ind = 1; ind < a.length; ind++) { final int r = random.nextInt(ind + 1); exch(a, ind, r); } }
217. Contains Duplicate
题意:判断数组中有无重复元素
我的思路:map水题
我的代码:
class Solution { public: bool containsDuplicate(vector<int>& nums) { map<int, int> mp; for (int i = 0; i < nums.size(); i++) { if (mp.find(nums[i]) != mp.end()) return 1; mp[nums[i]] = 1; } return 0; } };
solution解法:一行,集合
class Solution { public: bool containsDuplicate(vector<int>& nums) { return nums.size() > set<int>(nums.begin(), nums.end()).size(); } };
219. Contains Duplicate II
题意:判断数组中是否有两个相同元素且距离不大于k
我的思路:map水题
我的代码:
class Solution { public: bool containsNearbyDuplicate(vector<int>& nums, int k) { map<int, int> mp; for (int i = 0; i < nums.size(); i++) { if (mp.find(nums[i]) != mp.end() && i-mp[nums[i]] <= k) return 1; mp[nums[i]] = i; } return 0; } };
220. Contains Duplicate III
题意:判断数组中是否有差值不大于t的两个数,下标差值不大于k
思路:需要两个指针i和j,刚开始i和j都指向0,然后i开始向右走遍历数组,如果i和j之差大于k,且m中有nums[j],则删除并j加一。这样保证了m中所有的数的下标之差都不大于k,然后我们用map数据结构的lower_bound()函数来找一个特定范围,就是大于或等于nums[i] - t的地方,所有小于这个阈值的数和nums[i]的差的绝对值会大于t (可自行带数检验)。
我的代码:
class Solution { public: bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) { int j = 0; map<long long, int> m; for (int i = 0; i < nums.size(); i++) { if (i > k) m.erase(nums[j++]); map <long long, int> :: iterator it = m.lower_bound((long long)nums[i]-t); if (it != m.end() && abs(it->first-nums[i]) <= t) return 1; m[nums[i]] = i; } return 0; } };
223. Rectangle Area
题意:给定两个矩阵左下和右上的坐标,求总共占的面积
我的思路:数学题,也就是求共同区域面积
我的代码:
class Solution { public: int countDigitOne(int n) { if (n <= 0) return 0; int ans = 0; for (long long m = 1; ; m *= 10) { ans += n/(10*m)*m + ((n%(10*m)) >= m ? min(n%(10*m)-m+1, m) : 0); if (n/(10*m) == 0) break; } return ans; } };
228. Summary Ranges
题意:概述一个数组,比如given [0,1,2,4,5,7]
, return ["0->2","4->5","7"]
我的思路:处理好数字变字符串即可
我的代码:
class Solution { public: string num2str(int num) { string ans; bool flag = 0; if (num < 0) { ans += '-'; num = -num; if (num < 0) { flag = 1; num = 0x7fffffff; } } if (num == 0) ans += '0'; while (num > 0) { ans += '0'+num%10; num /= 10; } if (ans[0] == '-') reverse(ans.begin()+1, ans.end()); else reverse(ans.begin(), ans.end()); ans[ans.size()-1] += flag; return ans; } vector<string> summaryRanges(vector<int>& nums) { vector<string> ans; for (int i = 0; i < nums.size(); ) { string tmp = num2str(nums[i]); int j = i+1; while (j < nums.size() && nums[j] == nums[j-1]+1) j++; if (j == i+1) { ans.push_back(tmp); i++; continue; } tmp += "->"; tmp += num2str(nums[j-1]); ans.push_back(tmp); i = j; } return ans; } };
solution解法:to_string函数可以把数字变字符串不用自己写。。。
vector<string> summaryRanges(vector<int>& nums) { const int size_n = nums.size(); vector<string> res; if ( 0 == size_n) return res; for (int i = 0; i < size_n;) { int start = i, end = i; while (end + 1 < size_n && nums[end+1] == nums[end] + 1) end++; if (end > start) res.push_back(to_string(nums[start]) + "->" + to_string(nums[end])); else res.push_back(to_string(nums[start])); i = end+1; } return res; }
229. Majority Element II
题意:输出数组中个数超过1/3的元素
我的思路:摩尔最大投票算法,包括169题,https://segmentfault.com/a/1190000004905350
我的代码:
class Solution { public: vector<int> majorityElement(vector<int>& nums) { int n = nums.size(); if (n < 2) return nums; int major1 = 0x7fffffff, major2 = 0x80000000, cnt1 = 0, cnt2 = 0; for (int i = 0; i < n; i++) { if (nums[i] == major1) { cnt1++; } else if (nums[i] == major2) { cnt2++; } else if (cnt1 == 0) { major1 = nums[i]; cnt1++; } else if (cnt2 == 0) { major2 = nums[i]; cnt2++; } else { cnt1--; cnt2--; } } cnt1 = cnt2 = 0; for (int i = 0; i < n; i++) { if (nums[i] == major1) cnt1++; if (nums[i] == major2) cnt2++; } vector<int> ans; if (cnt1 > n/3) ans.push_back(major1); if (cnt2 > n/3) ans.push_back(major2); return ans; } };
231. Power of Two
题意:判断一个数是不是2的次方
我的思路:大水题
我的代码:
class Solution { public: bool isPowerOfTwo(int n) { while (n > 1) { if (n%2) return 0; n /= 2; } return n > 0 ? n : 0; } };
233. Number of Digit One
题意:输出从1到n的数字中有多少个1
我的思路:每10个数, 有一个个位是1, 每100个数, 有10个十位是1, 每1000个数, 有100个百位是1... 做一个循环, 每次计算单个位上1得总个数(个位,十位, 百位).
我的代码:
class Solution { public: int countDigitOne(int n) { if (n <= 0) return 0; long long ans = 0, m = 1; while (1) { ans += n/(10*m)*m + ((n%(10*m)) >= m ? min(n%(10*m)-m+1, m) : 0); if (n/(10*m) == 0) break; m *= 10; } return ans; } };
241. Different Ways to Add Parentheses
题意:给定一组数和操作符,返回所有加括号后的结果
我的思路:以操作符为界左右分治
我的代码:
class Solution { public: vector<int> diffWaysToCompute(string input) { vector<int> ans; for (int i = 0; i < input.size(); i++) if (input[i] == '+' || input[i] == '-' || input[i] == '*') { vector<int> a1 = diffWaysToCompute(input.substr(0, i)); vector<int> a2 = diffWaysToCompute(input.substr(i+1, input.size()-1-i)); for (int ii = 0; ii < a1.size(); ii++) for (int jj = 0; jj < a2.size(); jj++) { if (input[i] == '+') ans.push_back(a1[ii]+a2[jj]); else if (input[i] == '-') ans.push_back(a1[ii]-a2[jj]); else if (input[i] == '*') ans.push_back(a1[ii]*a2[jj]); } } if (ans.empty()) ans.push_back(atoi(input.c_str())); return ans; } };
258. Add Digits
题意:给定一个数,将它各位数相加直到一位数
我的思路:类似九进制,九个一循环
我的代码:
class Solution { public: int addDigits(int num) { return num ? (num%9 ? num%9 : 9) : 0; } };
solution解法:其实差点就能想到
class Solution { public: int addDigits(int num) { return 1 + (num - 1) % 9; } };
263. Ugly Number
题意:判断一个数是不是质因子只有2、3、5
我的思路:大水题
我的代码:
九章最优解:一样
264. Ugly Number II
题意:输出第n个丑数
我的思路:分别记录乘2、3、5的下标,后推取最小
我的代码:
class Solution { public: int nthUglyNumber(int n) { vector<int> num(n); num[0] = 1; int i2 = 0, i3 = 0, i5 = 0; for (int i = 1; i < n; i++) { num[i] = min(num[i2]*2, num[i3]*3); num[i] = min(num[i], num[i5]*5); if (num[i] == num[i2]*2) i2++; if (num[i] == num[i3]*3) i3++; if (num[i] == num[i5]*5) i5++; } return num[n-1]; } };
九章最优解:差不多
class Solution { public: /* * @param n an integer * @return the nth prime number as description. */ int nthUglyNumber(int n) { int *uglys = new int[n]; uglys[0] = 1; int next = 1; int *p2 = uglys; int *p3 = uglys; int *p5 = uglys; while (next < n){ int m = min(min(*p2 * 2, *p3 * 3), *p5 * 5); uglys[next] = m; while (*p2 * 2 <= uglys[next]) *p2++; while (*p3 * 3 <= uglys[next]) *p3++; while (*p5 * 5 <= uglys[next]) *p5++; next++; } int uglyNum = uglys[n - 1]; delete[] uglys; return uglyNum; } };
268. Missing Number
题意:给定一个长度n的数组,找出差0~n的哪个数
我的思路:水题
我的代码:
class Solution { public: int missingNumber(vector<int>& nums) { int b = 0; for (int i = 1; i < nums.size(); i++) { nums[0] ^= nums[i]; b ^= i; } return nums[0]^b^nums.size(); } };
九章最优解:
public class Solution { /** * @param nums: an array of integers * @return: an integer */ public int findMissing(int[] nums) { // write your code here int n = nums.length, i = 0; while (i<n) { while (nums[i]!=i && nums[i]<n) { int t = nums[i]; nums[i] = nums[t]; nums[t] = t; } ++i; } for (i=0; i<n; ++i) if (nums[i]!=i) return i; return n; } }
273. Integer to English Words
题意:int型非负数转英文
思路:三位三位来
我的代码:
class Solution { public: string str[4] = {"", "Thousand", "Million", "Billion"}; string less20[20] = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}; string tens[10] = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"}; string gg(int n) { if (n == 0) return ""; else if (n < 20) return less20[n]+" "; else if (n < 100) return tens[n/10]+" "+gg(n%10); else return less20[n/100]+" Hundred "+ gg(n%100); } string numberToWords(int num) { if (num == 0) return "Zero"; int i = 0, j; string ans = ""; while (num) { if (num%1000) ans = gg(num%1000)+str[i]+" "+ans; num /= 1000; i++; } i = 0, j = ans.size()-1; while (ans[i] == ' ') i++; while (ans[j] == ' ') j--; return ans.substr(i, j-i+1); } };
274. H-Index
题意:给定一个数组,输出H值:数组中至少有H个数大于等于H,H有多个答案时取最大的
我的思路:排序,从大往小找
我的代码:
class Solution { public: int hIndex(vector<int>& citations) { int i, n = citations.size(); sort(citations.begin(), citations.end()); for (i = 0; i < n; i++) if (citations[n-1-i] < i+1) break; return i; } };
九章最优解:
class Solution { public: int hIndex(vector<int>& citations) { int n = citations.size(); int num[n+1]; memset(num, 0, sizeof(num)); for (int i = 0; i < citations.size(); i++) { if (citations[i] >= n) { num[n] ++; } else { num[citations[i]] ++; } } int sum = 0; for (int i = n; i >= 0; i--) { sum += num[i]; if(sum >= i) return i; } return 0; } };
275. H-Index II
题意:跟上题一样,外加数组有序
我的思路:上题代码即可
我的代码:
class Solution { public: int hIndex(vector<int>& citations) { int i, n = citations.size(); for (i = 0; i < n; i++) if (citations[n-1-i] < i+1) break; return i; } };
九章最优解:二分啊!!有序数组都想不起来
class Solution { public: int hIndex(vector<int>& citations) { int ans = 0; int h; int l = 0, r = citations.size() - 1; while(l <= r) { int mid = (l + r)/2; h = citations.size() - mid; if (citations[mid] >= h) { ans = max(ans, h); r = mid - 1; } else { ans = max(ans, citations[mid]); l = mid + 1; } } return ans; } };
class Solution { public: vector<string> ans; void dfs(string num, long sum, string tmp, int target, int pos, long mul) { if (pos == num.size()) { if (sum == target) ans.push_back(tmp); return; } for (int i = pos; i < num.size(); i++) { if (i > pos && num[pos] == '0') break; long gg = stol(num.substr(pos, i-pos+1)); if (pos == 0) { dfs(num, sum+gg, tmp+num.substr(pos, i-pos+1), target, i+1, gg); } else { dfs(num, sum+gg, tmp+'+'+num.substr(pos, i-pos+1), target, i+1, gg); dfs(num, sum-gg, tmp+'-'+num.substr(pos, i-pos+1), target, i+1, -gg); dfs(num, sum-mul+mul*gg, tmp+'*'+num.substr(pos, i-pos+1), target, i+1, mul*gg); } } } vector<string> addOperators(string num, int target) { string tmp; dfs(num, 0, tmp, target, 0, 0); return ans; } };
class Solution { public: void moveZeroes(vector<int>& nums) { vector<int>:: iterator it; int n = nums.size(); for (it = nums.begin(); it != nums.end()-1;) if (*it == 0 ) it = nums.erase(it); else it++; int i = n-nums.size(); while (i--) nums.push_back(0); } };
九章最优解:双指针,右指针往后扫,遇非0与左换即可
class Solution { public: void moveZeroes(vector<int>& nums) { int left = 0, right = 0; while (right < nums.size()) { if (nums[right]) { swap(nums[left++], nums[right]); } right++; } } };
class Solution { public: int findDuplicate(vector<int>& nums) { sort(nums.begin(), nums.end()); for (int i = 1; i < nums.size(); i++) if (nums[i] == nums[i-1]) return nums[i]; } };
289. Game of Life
题意:水题,计数
我的代码:
class Solution { public: int dir[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}}; int hehe(vector<vector<int>>& board, int x, int y) { int m = board.size(), n = board[0].size(), ans = 0; for (int i = 0; i < 8; i++) { int xx = x+dir[i][0], yy = y+dir[i][1]; if (xx >= 0 && xx < m && yy >= 0 && yy < n && board[xx][yy]) ans++; } return ans; } void gameOfLife(vector<vector<int>>& board) { int m = board.size(), n = board[0].size(); vector<vector<int>> num(m, vector<int>(n)); for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) num[i][j] = hehe(board, i, j); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (board[i][j] && (num[i][j] < 2 || num[i][j] > 3)) board[i][j] = 0; else if (!board[i][j] && num[i][j] == 3) board[i][j] = 1; } } } };
290. Word Pattern
题意:判断字符串模式是不是给出的式样,如
- pattern =
"abba"
, str ="dog cat cat dog"
should return true. - pattern =
"abba"
, str ="dog cat cat fish"
should return false.
我的思路:map做两个方向的映射然后判断
我的代码:
class Solution { public: bool wordPattern(string pattern, string str) { unordered_map<char, string> hash1; unordered_map<string, char> hash2; string tmp; int j = 0; for (int i = 0; i < str.length(); i++) { if (str[i] == ' ') { if (hash1.find(pattern[j]) != hash1.end()) { if (hash1[pattern[j]] != tmp) return 0; } if (hash2.find(tmp) != hash2.end()) { if (hash2[tmp] != pattern[j]) return 0; } if (hash1.find(pattern[j]) == hash1.end() && hash2.find(tmp) == hash2.end()) { hash1[pattern[j]] = tmp; hash2[tmp] = pattern[j]; } tmp = ""; j++; if (j >= pattern.length()) return 0; } else { tmp += str[i]; } } if (hash1.find(pattern[j]) != hash1.end()) { if (hash1[pattern[j]] != tmp) return 0; } if (hash2.find(tmp) != hash2.end()) { if (hash2[tmp] != pattern[j]) return 0; } if (j != pattern.length()-1) return 0; return 1; } };
九章最优解:无
292. Nim Game
题意:取石子游戏,一次可以取1-3个,无子可取为输, 给定石子个数n,问先取的人能不能赢
我的思路:模4不解释
我的代码:
class Solution { public: bool canWinNim(int n) { return (n%4 != 0); } };
295. Find Median from Data Stream
题意:输出数据流的中位数,可以添加数字
我的思路:开一个数组插入排序。。
我的代码:
class MedianFinder { public: vector<int> s; /** initialize your data structure here. */ MedianFinder() {} void addNum(int num) { int i = 0; while (i < s.size() && s[i] < num) i++; s.insert(s.begin()+i, num); } double findMedian() { int n = s.size(); if (n%2) return s[n/2]; return ((double)s[n/2-1]+s[n/2])/2; } };
solution解法:两个优先队列
class MedianFinder { priority_queue<long> small, large; public: void addNum(int num) { small.push(num); large.push(-small.top()); small.pop(); if (small.size() < large.size()) { small.push(-large.top()); large.pop(); } } double findMedian() { return small.size() > large.size() ? small.top() : (small.top() - large.top()) / 2.0; } };
299. Bulls and Cows
题意:求两个等长字符串中有多少个相同字符位置一样,多少个相同字符位置不一样
我的思路:相同同位的扫一遍就行,相同不等位的每个字符看它们都有多少个,取较小的数
我的代码:
class Solution { public: string getHint(string secret, string guess) { vector<int> num1(10, 0), num2(10, 0); int n = secret.size(), cnt = 0; for (int i = 0; i < n; i++) { if (secret[i] == guess[i]) cnt++; else { num1[secret[i]-'0']++; num2[guess[i]-'0']++; } } string ans; ans += to_string(cnt); ans += 'A'; cnt = 0; for (int i = 0; i < 10; i++) cnt += min(num1[i], num2[i]); ans += to_string(cnt); ans += 'B'; return ans; } };
301. Remove Invalid Parentheses
题意:给定一串括号,输出删除最少个括号使整个串合法的所有可能
我的思路:用一个count模拟栈,遇见左括号++count,遇见右括号就–count。 因为只有‘(’和‘)’我们先对‘)’进行处理,至于‘(’,我们只需要倒着再做一次即可。 在循环当中当且仅当我们找到一个多余的‘)’时,count<0(此处也保证了题目要求的最少量)。此时我们需要对当前的子串进行处理,即移除其中某个‘)’
我的代码:
class Solution { public: void remove(string s, vector<string> &ans, int li, int lj, vector<char> par) { for (int i = li, cnt = 0; i < s.size(); i++) { if (s[i] == par[0]) cnt++; if (s[i] == par[1]) cnt--; if (cnt < 0) { for (int j = lj; j <= i; j++) if (s[j] == par[1] && (j == lj || s[j-1] != par[1])) remove(s.substr(0, j)+s.substr(j+1, s.length()-j-1), ans, i, j, par); return; } } reverse(s.begin(), s.end()); if (par[0] == '(') remove(s, ans, 0, 0, vector<char> {')', '('}); else ans.push_back(s); } vector<string> removeInvalidParentheses(string s) { vector<string> ans; remove(s, ans, 0, 0, vector<char> {'(', ')'}); return ans; } };
307. Range Sum Query - Mutable
题意:区间求和,单点修改
我的思路:线段树点修改
我的代码:
class NumArray { public: struct Node { int l, r, sum; }; vector<Node> p; vector<int> num; void build(int l, int r, int i) { p[i].l = l; p[i].r = r; if (l == r) { p[i].sum = num[l]; return; } int mid = (l+r)/2; build(l, mid, i<<1); build(mid+1, r, i<<1|1); p[i].sum = p[i<<1].sum+p[i<<1|1].sum; } NumArray(vector<int> nums) { int n = nums.size(); if (n > 0) { num = nums; p.resize(n<<2); build(0, n-1, 1); } } void upd(int k, int add, int i) { if (p[i].l == p[i].r) { p[i].sum += add; return; } int mid = (p[i].l+p[i].r)>>1; if (k <= mid) upd(k, add, i<<1); else upd(k, add, i<<1|1); p[i].sum = p[i<<1].sum+p[i<<1|1].sum; } void update(int i, int val) { upd(i, val-num[i], 1); num[i] = val; } int query(int l, int r, int i) { if(l == p[i].l && p[i].r == r) return p[i].sum; int mid = (p[i].l+p[i].r)>>1; if (r<=mid) return query(l, r, i<<1); else if (l>mid) return query(l, r, (i<<1)+1); else return query(l, mid, i<<1)+query(mid+1, r, (i<<1)+1); } int sumRange(int i, int j) { return query(i, j, 1); } }; /** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * obj.update(i,val); * int param_2 = obj.sumRange(i,j); */
313. Super Ugly Number
题意:类似264题,给定一个质因子数组,输出他们相乘得到的第n个数,强制第一个为1
我的思路:跟264一样
我的代码:
class Solution { public: int nthSuperUglyNumber(int n, vector<int>& primes) { int m = primes.size(); vector<int> num(n), loc(m, 0); num[0] = 1; for (int i = 1; i < n; i++) { num[i] = num[loc[0]]*primes[0]; for (int j = 1; j < m; j++) num[i] = min(num[i], num[loc[j]]*primes[j]); for (int j = 0; j < m; j++) if (num[i] == num[loc[j]]*primes[j]) loc[j]++; } return num[n-1]; } };
九章最优解:一样
public class Solution { /** * @param n a positive integer * @param primes the given prime list * @return the nth super ugly number */ public int nthSuperUglyNumber(int n, int[] primes) { int[] times = new int[primes.length]; int[] uglys = new int[n]; uglys[0] = 1; for (int i = 1; i < n; i++) { int min = Integer.MAX_VALUE; for (int j = 0; j < primes.length; j++) { min = Math.min(min, primes[j] * uglys[times[j]]); } uglys[i] = min; for (int j = 0; j < times.length; j++) { if (uglys[times[j]] * primes[j] == min) { times[j]++; } } } return uglys[n - 1]; } }
315. Count of Smaller Numbers After Self
题意:输出数组中每个数字后边比他小的数字的个数
我的思路:归并排序
我的代码:
class Solution { public: void merge(int l, int mid, int r, vector<int> &ans, vector<pair<int, int>> &vec) { vector<pair<int, int>> tmp; int i = l, j = mid+1; for (i = l; i <= mid; i++) { while (j <= r && vec[i].first > vec[j].first) tmp.push_back(vec[j++]); tmp.push_back(vec[i]); ans[vec[i].second] += j-mid-1; } while(j <= r) tmp.push_back(vec[j++]); for (i = l; i <= r; i++) vec[i] = tmp[i-l]; } void mergesort(int l, int r, vector<int> &ans, vector<pair<int, int>> &vec) { if (l != r) { int mid = (l+r)/2; mergesort(l, mid, ans, vec); mergesort(mid+1, r, ans, vec); merge(l, mid, r, ans, vec); } } vector<int> countSmaller(vector<int>& nums) { int n = nums.size(); if (n == 0) return {}; vector<int> ans(n, 0); vector<pair<int, int>> vec; for(int i =0; i < n; i++) vec.push_back(make_pair(nums[i], i)); mergesort(0, n-1, ans, vec); return ans; } };
discuss解法:第一个,二叉搜索树
public class Solution { class Node { Node left, right; int val, sum, dup = 1; public Node(int v, int s) { val = v; sum = s; } } public List<Integer> countSmaller(int[] nums) { Integer[] ans = new Integer[nums.length]; Node root = null; for (int i = nums.length - 1; i >= 0; i--) { root = insert(nums[i], root, ans, i, 0); } return Arrays.asList(ans); } private Node insert(int num, Node node, Integer[] ans, int i, int preSum) { if (node == null) { node = new Node(num, 0); ans[i] = preSum; } else if (node.val == num) { node.dup++; ans[i] = preSum + node.sum; } else if (node.val > num) { node.sum++; node.left = insert(num, node.left, ans, i, preSum); } else { node.right = insert(num, node.right, ans, i, preSum + node.dup + node.sum); } return node; } }
316. Remove Duplicate Letters
题意:去掉字符串中的相同字符,并且返回保持相对顺序的字典序最小的那个
思路:discuss第一个,递归,对于串s,找到最小的s[i]从他往后包含所有的字符,那么他就是结果串的开始,把后边所有的s[i]去掉,递归这个过程
我的代码:
class Solution { public: string removeDuplicateLetters(string s) { vector<int> num(26, 0); int pos = 0; for (int i = 0; i < s.length(); i++) num[s[i]-'a']++; for (int i = 0; i < s.length(); i++) { if (s[i] < s[pos]) pos = i; if (--num[s[i]-'a'] == 0) break; } string ss; if (s.size() > 0) { ss = s.substr(pos+1); for (int i = 0; i < ss.size(); i++) if (ss[i] == s[pos]) ss.erase(i--, 1); } return s.size() == 0 ? "" : s[pos]+removeDuplicateLetters(ss); } };
solution解法:栈,读字符的过程中,把字符存到stack里,当发现stack之前存的字符中比当前字符大而且频率还大于0就可以把那个字符pop出去。
class Solution { public: string removeDuplicateLetters(string s) { int m[256] = {0}, visited[256] = {0}; string res = "0"; for (auto a : s) ++m[a]; for (auto a : s) { --m[a]; if (visited[a]) continue; while (a < res.back() && m[res.back()]) { visited[res.back()] = 0; res.pop_back(); } res += a; visited[a] = 1; } return res.substr(1); } };
318. Maximum Product of Word Lengths
题意:给定一组单词,判断其中没有重复字母的两个单词长度之积最大是多少
我的思路:关键就是一个整数位表示集合
我的代码:
class Solution { public: bool ok(string str1, string str2) { int ret1 = 0, ret2 = 0; for (int i = 0; i < str1.length(); i++) ret1 |= (1<<(str1[i]-'a')); for (int i = 0; i < str2.length(); i++) ret2 |= (1<<(str2[i]-'a')); for (int i = 0; i < 26; i++) { if ((ret1%2)&(ret2%2) == 1) return 0; ret1 /= 2; ret2 /= 2; } return 1; } int maxProduct(vector<string>& words) { int ans = 0; for (int i = 0; i < words.size(); i++) for (int j = i+1; j < words.size(); j++) if (ok(words[i], words[j])) ans = max(ans, (int)words[i].size()*(int)words[j].size()); return ans; } };
九章最优解:无
319. Bulb Switcher
题意:给定n,有n盏关闭的灯(编号1开始),进行n次操作,第i次改变编号为i的倍数的灯的状态,求最后有几盏灯是亮的
我的思路:最终是求不大于n的最大的平方数的平方根。因为n从小往大来看,当n有偶数个小于等于他的因子时,最后亮灯的个数相比于n-1不会增加,而n非平方数时都有偶数个因子,所以结果是逢平方数加一
我的代码:
class Solution { public: int bulbSwitch(int n) { return (int)sqrt(n); } };
九章最优解:无
324. Wiggle Sort II
题意:将一个无序数组排成nums[0] < nums[1] > nums[2] < nums[3]...
.
思路:http://blog.csdn.net/qq508618087/article/details/51337187
代码:
class Solution { public: int index(int pos, int n) { return (2*pos+1)%(n|1); } void wiggleSort(vector<int>& nums) { nth_element(nums.begin(), nums.begin()+nums.size()/2, nums.end()); int n = nums.size(), l = 0, h = n-1, mid = nums[n/2], i = 0; while (i <= h) { if (nums[index(i, n)] > mid) swap(nums[index(i++, n)], nums[index(l++, n)]); else if (nums[index(i, n)] < mid) swap(nums[index(i, n)], nums[index(h--, n)]); else i++; } } };
326. Power of Three
题意:判断一个数是否为3的幂
我的思路:找到整数范围内最大的3的幂max,如果这个数是3的幂,他一定能整除max
我的代码:
class Solution { public: bool isPowerOfThree(int n) { int maxPower = (int) pow(3,(int)(log(0x7fffffff)/log(3))); return n > 0 && (maxPower%n == 0); } };
solution解法:很多,包括我这个
https://leetcode.com/problems/power-of-three/solution/
329. Longest Increasing Path in a Matrix
题意:输出数组中数字的最长上升路径长度
我的思路:dfs+记忆化搜索
我的代码:
class Solution { public: const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; int dfs(vector<vector<int>>& matrix, vector<vector<int>>& num, int x, int y) { if (num[x][y] > 1) return num[x][y]; for (int i = 0; i < 4; i++) { int xx = x+dir[i][0], yy = y+dir[i][1]; if (xx >= 0 && xx < matrix.size() && yy >= 0 && yy < matrix[0].size() && matrix[xx][yy] > matrix[x][y]) num[x][y] = max(num[x][y], dfs(matrix, num, xx, yy)+1); } return num[x][y]; } int longestIncreasingPath(vector<vector<int>>& matrix) { if (matrix.size() == 0) return 0; int m = matrix.size(), n = matrix[0].size(); vector<vector<int> > num(m, vector<int>(n, 1)); int ans = 0; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) ans = max(ans, dfs(matrix, num, i, j)); return ans; } };
330. Patching Array
题意:求往数组中添加最少数量的数字,使数组中数字求和可以得到[1, n]
思路:discuss第一个
代码:
class Solution { public: int minPatches(vector<int>& nums, int n) { long long maxn = 1, ans = 0, i = 0; while (maxn <= n) { if (i < nums.size() && nums[i] <= maxn) maxn += nums[i++]; else { ans++; maxn += maxn; } } return ans; } };
338. Counting Bits
题意:给定n,返回一个数组表示0~n的二进制分别有几个1,要求时间、空间复杂度O(n)
我的思路:类似格雷码的想法,后2^n个数中1的个数是前2^n个数相应位置的个数加一
我的代码:想法不错且1A
class Solution { public: vector<int> countBits(int num) { vector<int> ans(num+1); ans[0] = 0; int pow2 = 1, sum_pow2 = 1; for (int i = 1; i <= num; i++) { if (sum_pow2 < i) { pow2 *= 2; sum_pow2 += pow2; } ans[i] = ans[i-pow2]+1; } return ans; } };
341. Flatten Nested List Iterator
题意:将一个不定长list展开,具体细节看题
我的思路:递归
我的代码:
class NestedIterator { public: int k; vector<int> ans; void helper(vector<NestedInteger> &l) { for (int i = 0; i < l.size(); i++) { if (l[i].isInteger()) ans.push_back(l[i].getInteger()); else helper(l[i].getList()); } } NestedIterator(vector<NestedInteger> &nestedList) { k = 0; helper(nestedList); } int next() { return ans[k++]; } bool hasNext() { return k < ans.size(); } };
342. Power of Four
题意:判断一个数是否是4的幂
我的思路:先判断是不是2的幂,再判断1是否在奇数位
我的代码:
class Solution { public: bool isPowerOfFour(int num) { if (num & (num-1)) return 0; return num & 0x55555555; } };
九章最优解:无
344. Reverse String
题意:将一个字符串翻转
我的思路:大水题
我的代码:
class Solution { public: string reverseString(string s) { int n = s.length(); for (int i = 0; i < n/2; i++) { char c = s[i]; s[i] = s[n-1-i]; s[n-1-i] = c; } return s; } };
345. Reverse Vowels of a String
题意:将一个字符串的所有元音字母前后翻转,其他字母不动
我的思路:大水题
我的代码:
class Solution { public: bool isvow(char c) { return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u' || c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U'; } string reverseVowels(string s) { int l = 0, r = s.length()-1; while (l < r) { if (isvow(s[l]) == 0) l++; if (isvow(s[r]) == 0) r--; if (isvow(s[l]) && isvow(s[r])) { char c = s[l]; s[l] = s[r]; s[r] = c; l++; r--; } } return s; } };
349. Intersection of Two Arrays
题意:给定两个有重复元素的数组,输出交集
我的思路:使用STL函数去重及交集操作
我的代码:
public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { vector<int> ans; if (nums1.size() == 0 || nums2.size() == 0) return ans; ans.resize(nums1.size()); vector<int>::iterator it; sort(nums1.begin(), nums1.end()); nums1.erase(unique(nums1.begin(), nums1.end()), nums1.end()); sort(nums2.begin(), nums2.end()); nums2.erase(unique(nums2.begin(), nums2.end()), nums2.end()); it = set_intersection(nums1.begin(), nums1.end(), nums2.begin(), nums2.end(), ans.begin()); ans.resize(it-ans.begin()); return ans; } };
九章最优解:先排序,之后两个指针提交集
class Solution { public: /** * @param nums1 an integer array * @param nums2 an integer array * @return an integer array */ vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { // Write your code here sort(nums1.begin(), nums1.end()); sort(nums2.begin(), nums2.end()); vector<int> intersect; vector<int>::iterator it1 = nums1.begin(), it2 = nums2.begin(); while ((it1 != nums1.end()) && (it2 != nums2.end())) { if (*it1 < *it2) it1++; else if (*it1 > *it2) it2++; else { intersect.push_back(*it1); it1++; it2++; } } auto last = unique(intersect.begin(), intersect.end()); intersect.erase(last, intersect.end()); return intersect; } };
350. Intersection of Two Arrays II
题意:给定两个含有重复元素的数组,输出所有重复元素
我的思路:比上题还简单些,去重去掉
我的代码:
class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { vector<int> ans; if (nums1.size() == 0 || nums2.size() == 0) return ans; ans.resize(nums1.size()); vector<int>::iterator it; sort(nums1.begin(), nums1.end()); sort(nums2.begin(), nums2.end()); it = set_intersection(nums1.begin(), nums1.end(), nums2.begin(), nums2.end(), ans.begin()); ans.resize(it-ans.begin()); return ans; } };
九章最优解:
class Solution { public: /** * @param nums1 an integer array * @param nums2 an integer array * @return an integer array */ vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { // Write your code here sort(nums1.begin(), nums1.end()); sort(nums2.begin(), nums2.end()); vector<int> intersect; vector<int>::iterator it1 = nums1.begin(), it2 = nums2.begin(); while ((it1 != nums1.end()) && (it2 != nums2.end())) { if (*it1 < *it2) it1++; else if (*it1 > *it2) it2++; else { intersect.push_back(*it1); it1++; it2++; } } return intersect; } };
357. Count Numbers with Unique Digits
题意:求0~10^n中由全不相同数字组成的整数个数
我的思路:可以算的
我的代码:
class Solution { public: int countNumbersWithUniqueDigits(int n) { if (n > 10) return 0; if (n == 0) return 1; if (n == 1) return 10; int k = 9, ans = 10; for (int i = 0, j = 9; i <n-1; i++) { k *= j-i; ans += k; } return ans; } };
365. Water and Jug Problem
题意:给两个容积分别为x,y的杯子,问是否能量出z的水来
我的思路:如果z%(x+y)==0就可以
我的代码:
class Solution { public: int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); } bool canMeasureWater(int x, int y, int z) { return !z || (x+y >= z && z%gcd(x, y) == 0); } };
367. Valid Perfect Square
题意:不用sqrt判断完全平方数
我的思路:二分,注意不要超int
我的代码:
class Solution { public: bool isPerfectSquare(int num) { int l = 1, r = num/2; while (l+1 < r) { int mid = (l+r)/2; if (mid > num/mid) r = mid; else l = mid; } return l*l == num || r*r == num; } };
九章最优解:无
371. Sum of Two Integers
题意:不使用加号求两数之和
我的思路:位运算,见 http://blog.csdn.net/zhongjiekangping/article/details/6855864
我的代码:
class Solution { public: int getSum(int a, int b) { while (a&b) { int c = ((a&b)<<1); a = a^b; b = c; } return a^b; } };
九章最优解:无
372. Super Pow
题意:输出a^b%1337,b由数组形式给出
我的思路:数论
我的代码:
class Solution { public: const int mod = 1337; int quick_mod(int a, int b) { int ans = 1; a %= mod; for (int i = 0; i < b; i++) ans = ans*a%mod; return ans; } int superPow(int a, vector<int>& b) { if (b.size() == 0) return 1; int wei = b.back(); b.pop_back(); return quick_mod(superPow(a, b), 10)*quick_mod(a, wei)%mod; } };
373. Find K Pairs with Smallest Sums
题意:给定两个升序数组,各拿一个数字输出和最小的前k组
我的思路:排序,很慢
我的代码:
class Solution { public: static bool cmp(const pair<int, int>& a, const pair<int, int>& b) { return a.first+a.second < b.first+b.second; } vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) { vector<pair<int, int>> tmp; for (int i = 0; i < nums1.size(); i++) for (int j = 0; j < nums2.size(); j++) tmp.push_back(make_pair(nums1[i], nums2[j])); sort(tmp.begin(), tmp.end(), cmp); vector<pair<int, int>> ans; for (int i = 0; i < nums1.size()*nums2.size() && i < k; i++) ans.push_back(tmp[i]); return ans; } };
discuss解法:优先队列
class Solution { public: struct Item { pair<int, int> num; int id; bool operator < (const Item& a) const { return num.first+num.second > a.num.first+a.num.second; } }; vector<pair<int, int>> kSmallestPairs(vector<int>& nums1, vector<int>& nums2, int k) { priority_queue<Item> pq; vector<pair<int, int>> ans; if (nums1.size() == 0 || nums2.size() == 0 || k == 0) return ans; for (int i = 0; i < nums1.size() && i < k; i++){ Item item; item.num = make_pair(nums1[i], nums2[0]); item.id = 0; pq.push(item); } while (k-- > 0 && !pq.empty()) { Item tmp = pq.top(); pq.pop(); ans.push_back(tmp.num); if (tmp.id == nums2.size()-1) continue; tmp.num = make_pair(tmp.num.first, nums2[tmp.id+1]); tmp.id++; pq.push(tmp); } return ans; } };
374. Guess Number Higher or Lower
题意:告诉你高了还是低了猜数字
我的思路:二分水题
我的代码:
int guess(int num); class Solution { public: int guessNumber(int n) { int l = 1, r = n; while (l+1<r) { int mid = l+(r-l)/2; if (guess(mid) == 0) return mid; else if (guess(mid) < 0) r = mid; else l= mid; } return guess(l) == 0 ? l : r; } };
376. Wiggle Subsequence
题意:求最长的波浪数列长度
我的思路:找上升沿和下降沿
我的代码:
class Solution { public: int wiggleMaxLength(vector<int>& nums) { int n = nums.size(), ans = 1, flag, i = 1; if (n <= 1) return n; while (i < n && nums[i] == nums[i-1]) i++; if (i >= n) return 1; if (nums[i] > nums[i-1]) flag = 1; else flag = 0; while (i < n) { if (flag && nums[i] > nums[i-1]) { while (i < n && nums[i] > nums[i-1]) i++; ans++; flag ^= 1; } else if (!flag && nums[i] < nums[i-1]){ while (i < n && nums[i] < nums[i-1]) i++; ans++; flag ^= 1; } else i++; } return ans; } };
380. Insert Delete GetRandom O(1)
题意:以O(1)的时间复杂度插入、删除、随机取数字
我的思路:map+vector
我的代码:
class RandomizedSet { public: unordered_map<int, int> m; vector<int> num; /** Initialize your data structure here. */ RandomizedSet() { } /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ bool insert(int val) { if (m.find(val) == m.end()) { m[val] = num.size(); num.push_back(val); return 1; } return 0; } /** Removes a value from the set. Returns true if the set contained the specified element. */ bool remove(int val) { if (m.find(val) != m.end()) { m[num[num.size()-1]] = m[val]; num[m[val]] = num[num.size()-1]; num.pop_back(); m.erase(val); return 1; } return 0; } /** Get a random element from the set. */ int getRandom() { return num[rand()%num.size()]; } };
383. Ransom Note
题意:给定a,b 两串,问a能否由b中找字母构成
我的思路:大水题
我的代码:
class Solution { public: bool canConstruct(string ransomNote, string magazine) { vector<int> cnt1(26, 0), cnt2(26, 0); for (int i = 0; i < ransomNote.length(); i++) cnt1[ransomNote[i]-'a']++; for (int i = 0; i < magazine.length(); i++) cnt2[magazine[i]-'a']++; for (int i = 0; i < 26; i++) if (cnt1[i] > cnt2[i]) return 0; return 1; } };
384. Shuffle an Array
题意:给定一个数组,shuffle函数可以把它打乱成任意一个排列,且不同排列概率相等;reset函数回复这个数组
我的思路:遍历数组,每个位置产生一个随机数与他交换,则可实现任意打乱
我的代码:
class Solution { public: vector<int> a; Solution(vector<int> nums) { a = nums; } /** Resets the array to its original configuration and return it. */ vector<int> reset() { return a; } /** Returns a random shuffling of the array. */ vector<int> shuffle() { vector<int> ret = a; for (int i = 0; i < ret.size(); i++) { int b = rand()%ret.size(); swap(ret[i], ret[b]); } return ret; } };
387. First Unique Character in a String
题意:找到字符串中第一个只出现一次的字符的位置
我的思路:统计个数
我的代码:
class Solution { public: int firstUniqChar(string s) { vector<int> cnt(26, 0); for (int i = 0; i < s.length(); i++) cnt[s[i]-'a']++; for (int i = 0; i < s.length(); i++) if (cnt[s[i]-'a'] == 1) return i; return -1; } };
388. Longest Absolute File Path
题意:输出最长的文件路径
我的思路:栈
我的代码:
class Solution { public: int lengthLongestPath(string input) { int ans = 0, i = 0, tmp = 0, num = 0, flag = 0; vector<int> s; input += "\n"; while (i < input.length()) { if (input[i] == '.') flag = 1; if (input[i] == '\n') { i++; if (s.size() > 0) tmp += s[s.size()-1]+1; s.push_back(tmp); tmp = 0; if (flag) { ans = max(ans, s[s.size()-1]); flag = 0; } while (i < input.length() && input[i] == '\t') { num++; i++; } while (s.size() > num) s.pop_back(); num = 0; } else { tmp++; i++; } } return ans; } };
389. Find the Difference
题意:输出b比a串中多出的一个字符
我的思路:水题,统计个数
我的代码:
class Solution { public: char findTheDifference(string s, string t) { vector<int> num1(26, 0), num2(26, 0); for (int i = 0; i < s.size(); i++) num1[s[i]-'a']++; for (int i = 0; i < t.size(); i++) num2[t[i]-'a']++; for (int i = 0; i < 26; i++) if (num2[i] > num1[i]) return 'a'+i; } };
solution解法:抑或啊啊啊
class Solution { public: char findTheDifference(string s, string t) { char r=0; for(char c:s) { r ^= c; } for(char c:t){ r ^=c; } return r; } };
390. Elimination Game
题意:给定一个数组,第一轮从左往右每个一个数删一个数,第二轮从右往左隔一个删一个数,一次循环直到只剩一个数,输出最后剩下的数
我的思路:递归,从左往右删[1, n ]等价于删[1, n/2]最后再乘2,从右往左删分两种情况,n为奇数等价于从左往右删,n为偶数,等价于删[1, n/2]再乘2减1
我的代码:
class Solution { public: int dfs(int t, bool flag) { if (t == 1) return 1; if (flag == 0) return dfs(t/2, 1)*2; else if (flag && t%2) return dfs(t/2, 0)*2; else return dfs(t/2, 0)*2-1; } int lastRemaining(int n) { return dfs(n, 0); //0 从左往右; 1 从右往左 } };
solution解法:逻辑帝。。
class Solution { public: int lastRemaining(int n) { return n==1? 1 : 2*(1 + n/2 - lastRemaining(n/2)); } };
392. Is Subsequence
题意:问a串是否是b串的子串
我的思路:两个循环对比
我的代码:
class Solution { public: bool isSubsequence(string s, string t) { int m = s.size(), n = t.size(), i = 0, j = 0; if (m == 0) return 1; while (j < n) { if (s[i] == t[j]) i++; j++; if (i == m) return 1; } return 0; } };
九章最优解:一样
393. UTF-8 Validation
题意:判断合法的unicode码
我的思路:水题
我的代码:
class Solution { public: bool validUtf8(vector<int>& data) { int cnt = 0; for (int i = 0; i < data.size(); i++) { if (!cnt) { if (data[i]>>5 == 0b110) cnt = 1; else if (data[i]>>4 == 0b1110) cnt = 2; else if (data[i]>>3 == 0b11110) cnt = 3; else if (data[i]>>7) return 0; continue; } if ((data[i]>>6) != 0b10) return 0; cnt--; } return !cnt; } };
394. Decode String
题意:解码,例如 :s = "3[a]2[bc]", return "aaabcbc". s = "3[a2[c]]", return "accaccacc". s = "2[abc]3[cd]ef", return "abcabccdcdcdef".串里边保证没有数字
我的思路:栈
我的代码:
class Solution { public: string decodeString(string s) { string ans; stack<int> nums; stack<string> str; int i = 0; while (i < s.size()) { if (isdigit(s[i])) { int num = 0; while (isdigit(s[i])) num = num*10+s[i++]-'0'; nums.push(num); } else if (s[i] == '[') { str.push(ans); ans = ""; i++; } else if (s[i] == ']') { string tmp = str.top(); str.pop(); int numt = nums.top(); nums.pop(); for (int j = 0; j < numt; j++) tmp += ans; ans = tmp; i++; } else { ans += s[i]; i++; } } return ans; } };
solution解法:
class Solution { public: string findParse(string s, int& start) { string out; while(start < s.size() && s[start] != ']') { if(!isdigit(s[start])) { out += s[start++]; continue; } int n = 0; while(isdigit(s[start])) { n = n*10 + s[start] - '0'; start++; } // cout<<"n "<<n<<endl; start++; string temp = findParse(s, start); start++; while(n--) { out += temp; } } return out; } string decodeString(string s) { int start = 0; return findParse(s, start); } };
395. Longest Substring with At Least K Repeating Characters
题意:输出字符串的最大子串长度,子串中每个字符不小于k个
我的思路:分治,若一个串每个字符不小于k个,则返回它的长度,否则以小于k个的字符为间断点递归调用这个函数
我的代码:
class Solution { public: int longestSubstring(string s, int k) { vector<int> num(26, 0); for (int i = 0; i < s.length(); i++) num[s[i]-'a']++; bool flag = 1; for (int i = 0; i < 26; i++) if (num[i] > 0 && num[i] < k) flag = 0; if (flag) return s.length(); int l = 0, r = 0, maxn = 0; while (r < s.length()) { if (num[s[r]-'a'] > 0 && num[s[r]-'a'] < k) { maxn = max(maxn, longestSubstring(s.substr(l, r-l), k)); l = r+1; } r++; } maxn = max(maxn, longestSubstring(s.substr(l, r-l), k)); return maxn; } };
396. Rotate Function
题意:将数组元素循环附以系数1~(n-1)求和,输出最大的
我的思路:
F(k) - F(k-1) = Bk[1] + Bk[2] + ... + Bk[n-1] + (1-n)Bk[0]
= (Bk[0] + ... + Bk[n-1]) - nBk[0]
= sum - nBk[0]
我的代码:
class Solution { public: int maxRotateFunction(vector<int>& A) { int n = A.size(), sum = 0, F = 0; for (int i = 0; i < n; i++) { sum += A[i]; F += i*A[i]; } int ans = F; for (int k = 1; k < n; k++) { F = F+sum-n*A[n-k]; ans = max(ans, F); } return ans; } };
397. Integer Replacement
题意:给一个整数,偶数可以变成n/2,奇数可以变成n-1或者n+1,求最少多少步可以变成1
我的思路:递归
我的代码:
class Solution { public: int integerReplacement(int n) { if (n <= 1) return 0; if (n == 0x7fffffff) return 32; return (n%2 ? min(integerReplacement(n-1), integerReplacement(n+1))+1 : integerReplacement(n>>1)+1); } };
398. Random Pick Index
题意:随机输出数组中值为target的标签中的一个
我的思路:蓄水池采样,总是选择第一个对象,以1/2的概率选择第二个,以1/3的概率选择第三个,以此类推,以1/m的概率选择第m个对象。当该过程结束时,每一个对象具有相同的选中概率,即1/n。
我的代码:
class Solution { public: vector<int> num; Solution(vector<int> nums) { num = nums; } int pick(int target) { int cnt = 0, ans; for (int i = 0; i < num.size(); i++) if (num[i] == target) { cnt++; if (rand()%cnt == 0) ans = i; } return ans; } };
题意:输出从1开始的第n个数字
我的思路:1位数9个,2位数90个,3位数900个,...
我的代码:
class Solution { public: int findNthDigit(int n) { long long l = 0, k = 1; while (l < n) { l += 9*k*pow(10, k-1); k++; } k--; l -= 9*k*pow(10, k-1); if ((n-l)%k == 0){ return ((n-l)/k-1)%10+(k == 1); } else { string tmp = to_string(pow(10, k-1)+(n-l)/k); return tmp[(n-l)%k-1]-'0'; } } };
399. Evaluate Division
题意:给定若干除法,字符串表示除数、被除数,输出若干除法询问的值,未知输出-1
我的思路:hash+dfs
我的代码:
class Solution { public: double dfs(string f, string t, unordered_map<string, unordered_map<string, double>>& m, unordered_set<string> s) { if (m[f].find(t) != m[f].end()) return m[f][t]; s.insert(f); for (auto i: m[f]) { if (s.find(i.first) == s.end()) { double tmp = dfs(i.first, t, m, s); if (tmp) return i.second*tmp; } } return 0; } vector<double> calcEquation(vector<pair<string, string>> equations, vector<double>& values, vector<pair<string, string>> queries) { unordered_map<string, unordered_map<string, double>> m; for (int i = 0; i < equations.size(); i++) { m[equations[i].first][equations[i].second] = values[i]; if (values[i]) m[equations[i].second][equations[i].first] = 1.0/values[i]; } vector<double> ans; unordered_set<string> s; for (int i = 0; i < queries.size(); i++) { double tmp = dfs(queries[i].first, queries[i].second, m, s); if (tmp) ans.push_back(tmp); else ans.push_back(-1); } return ans; } };
402. Remove K Digits
题意:给定一串数字字符串,删除k个使结果数字最小
我的思路:栈,升序入栈,降序删除栈位元素(删除总数不到k时)直到小于当前数字
我的代码:
class Solution { public: string removeKdigits(string num, int k) { if (num.length() <= k) return "0"; vector<char> s; int n = num.length(), cnt = 0; for (int i = 0; i < n; i++) { if (s.empty() || num[i] >= s.back() || cnt >= k) s.push_back(num[i]); else { while (!s.empty() && num[i] < s.back() && cnt < k) { s.pop_back(); cnt++; } s.push_back(num[i]); } } s.resize(num.size()-k); string ans(s.begin(), s.end()); int i = 0; while (i < ans.size()-1 && ans[i] == '0') i++; return ans.substr(i, ans.size()-i); } };
class Solution { public: string removeKdigits(string num, int k) { if (num.length() <= k) return "0"; vector<char> s; int n = num.length(), cnt = 0; for (int i = 0; i < n; i++) { while (!s.empty() && num[i] < s.back() && cnt < k) { s.pop_back(); cnt++; } s.push_back(num[i]); } s.resize(num.size()-k); string ans(s.begin(), s.end()); int i = 0; while (i < ans.size()-1 && ans[i] == '0') i++; return ans.substr(i, ans.size()-i); } };
403. Frog Jump
题意:给定一个数组,第一个一定是0,从他往后可以跳1个,往后
思路:discuss第一个
我的代码:
class Solution { public: bool canCross(vector<int>& stones) { int n = stones.size(); if (n <= 1) return 1; unordered_map<int, unordered_set<int>> m; m[0].insert(1); for (int i = 0; i < n; i++) for (auto step : m[stones[i]]) { int reach = step+stones[i]; if (reach == stones[n-1]) return 1; if (step > 1) m[reach].insert(step-1); m[reach].insert(step); m[reach].insert(step+1); } return 0; } };
405. Convert a Number to Hexadecimal
题意:数字转16进制,不能用STL
我的思路:先转二,再每四位转16
我的代码:太挫了
class Solution { public: string toHex(int num) { if (num == 0) return "0"; vector<int> bin(32); char b2h[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; bool flag = (num < 0); int gg = (num < 0 && -num< 0); if (flag) num = -num; if (gg) num = -(num+1); for (int i = 0; i < 32; i++) { bin[i] = num%2; num /= 2; } if (flag) { for (int i = 0; i < 32; i++) bin[i] ^= 1; if (!gg) bin[0] += 1; int jin = 0; for (int i = 0; i < 32; i++) { int tmp = bin[i]+jin; bin[i] = tmp%2; jin = tmp/2; } } string ans; for (int i = 0; i < 32; i += 4) { int tmp = 0; for (int j = 3; j >= 0; j--) tmp = tmp*2+bin[i+j]; ans += b2h[tmp]; } int k = 7; while (ans[k] == '0') { ans = ans.substr(0, ans.length()-1); k--; } for (int i= 0; i < ans.length()/2; i++) { char c = ans[i]; ans[i] = ans[ans.length()-1-i]; ans[ans.length()-1-i] = c; } return ans; } };
solution解法:
class Solution { public: string toHex(int num) { auto n = num & 0x00000000ffffffffL; string hex ="0123456789abcdef"; string res =""; while(n > 0){ int ret = n % 16; res += hex[ret]; n = n/16; } reverse(res.begin(),res.end()); return num == 0 ? "0" :res; } };
406. Queue Reconstruction by Height
题意:给定一组数对[h, k],h表示这个人的身高,k表示这个人前边有几个人身高大于等于他,将这组数对重排至合规
我的思路:按身高由大到小排队,身高一样的按k由小到大排序,从头遍历,k是几,插入到ans的第几个
我的代码:
class Solution { public: static bool cmp(const pair<int, int>& a, pair<int, int>& b) { return (a.first == b.first) ? a.second < b.second : a.first > b.first; } vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) { sort(people.begin(), people.end(), cmp); vector<pair<int, int>> ans; for (int i = 0; i < people.size(); i++) { ans.insert(ans.begin()+people[i].second, people[i]); } return ans; } };
九章最优解:一样哒!
class Solution { public: vector<pair<int, int>> reconstructQueue(vector<pair<int, int>>& people) { sort(people.begin(), people.end(), comparator); vector<pair<int, int>> resultVector; for (pair<int, int> cur : people) { resultVector.insert(resultVector.begin() + cur.second, cur); } return resultVector; } static bool comparator(pair<int, int> p1, pair<int, int> p2) { return (p1.first > p2.first) || (p1.first == p2.first && p1.second < p2.second); } };
409. Longest Palindrome
题意:给定一个包含大小写字母的字符串,求他的字母最多可以组成一个多长的回文串
我的思路:算每个字母的个数即可
我的代码:
class Solution { public: int longestPalindrome(string s) { vector<int> numda(26, 0); vector<int> numxi(26, 0); int n = s.size(); for (int i = 0; i < n; i++) { if (s[i] >= 'a' && s[i] <= 'z') numxi[s[i]-'a']++; else numda[s[i]-'A']++; } int ou = 0, flagji = 0; for (int i = 0; i < 26; i++) { if (numda[i]%2) flagji = 1; ou += numda[i]-numda[i]%2; if (numxi[i]%2) flagji = 1; ou += numxi[i]-numxi[i]%2; } return ou+flagji; } };
solution解法:基本思路一样,写的更简洁些
class Solution { public: int longestPalindrome(string s) { int dict[52]={0}; int even=0; int odd=0; for (int i=0; i<s.length(); i++){ if(s[i]>='A' && s[i]<='Z'){ if(++dict[s[i]-'A']%2==0) even++; }else{ if(++dict[s[i]-'a'+26]%2==0) even++; } } for (int i=0; i<52; i++){ if (dict[i]%2==1){ odd=1; break; } } return odd+even*2; } };
410. Split Array Largest Sum
题意:将数组分成m段,输出m个和中的最大值最小是多少
我的思路:poj3273,最大值最小化+二分
我的代码:
class Solution { public: bool judge(vector<int>& nums, int m, int mid) { int cnt = 0, k = 1; for (int i = 0; i < nums.size(); i++) { cnt += nums[i]; if (cnt > mid) { k++; cnt = nums[i]; } } return k>m; } int splitArray(vector<int>& nums, int m) { long long l = 0, r = 0; for (int i = 0; i < nums.size(); i++) { if (nums[i] > l) l = nums[i]; r += nums[i]; } while (l < r) { int mid = l+(r-l)/2; if (judge(nums, m, mid)) l = mid+1; else r = mid; } return r; } };
412. Fizz Buzz
题意:大水题
class Solution { public: vector<string> fizzBuzz(int n) { vector<string> ans; for (int i = 1; i <= n; i++) { if (i%3 == 0 && i%5 == 0) ans.push_back("FizzBuzz"); else if (i%3 == 0) ans.push_back("Fizz"); else if (i%5 == 0) ans.push_back("Buzz"); else ans.push_back(to_string(i)); } return ans; } };
413. Arithmetic Slices
题意:规定一个长度不小于3的等差数列称为A~S~,给定一个数组,求能找到多少个这种数列
我的思路:将数组变成后项减前项的差
我的代码:
class Solution { public: int count(int n) { return (n-1)*(n-2)/2; } int numberOfArithmeticSlices(vector<int>& A) { if (A.size() < 3) return 0; for (int i = 0; i < A.size()-1; i++) A[i] = A[i+1]-A[i]; int n = 1, ans = 0; for (int i = 1; i < A.size(); i++) { if (i < A.size()-1 && A[i] == A[i-1]) n++; else { if (n > 1) ans += count(n+1); n = 1; } } return ans; } };
solution解法:
class Solution { public: int numberOfArithmeticSlices(vector<int>& A) { int ans=0,dp=0; if(A.size()<=2) return 0; for(int i=2;i<A.size();i++) { if((A[i-1]-A[i-2])==(A[i]-A[i-1])) { dp=dp+1; ans+=dp; } else dp=0; } return ans; } };
414. Third Maximum Number
题意:输出数组中不重复的第三大的数,若没有,输出最大的数
我的思路:开个长度为3的数组保存前三大的数,更新
我的代码:
class Solution { public: int thirdMax(vector<int>& nums) { vector<long long> ans(3, 0x8000000000000000); for (int i = 0; i < nums.size(); i++) { if (nums[i] > ans[0]) ans[2] = ans[1], ans[1] = ans[0], ans[0] = nums[i]; else if (nums[i] != ans[0] && nums[i] > ans[1]) ans[2] = ans[1], ans[1] = nums[i]; else if (nums[i] != ans[0] && nums[i] != ans[1] && nums[i] > ans[2]) ans[2] = nums[i]; else continue; } return ans[2] == 0x8000000000000000 ? ans[0] : ans[2]; } };
415. Add Strings
题意:大数加法
我的思路 :常规字符串处理
我的代码:
class Solution { public: string addStrings(string num1, string num2) { int m = num1.length(), n = num2.length(), i = 0, jin = 0; reverse(num1.begin(), num1.end()); reverse(num2.begin(), num2.end()); string ans; while (i < m && i < n) { int tmp = num1[i]-'0'+num2[i]-'0'+jin; ans += tmp%10+'0'; jin = tmp/10; i++; } while (i < m) { int tmp = num1[i]-'0'+jin; ans += tmp%10+'0'; jin = tmp/10; i++; } while (i < n) { int tmp = num2[i]-'0'+jin; ans += tmp%10+'0'; jin = tmp/10; i++; } if (jin) ans += jin+'0'; reverse(ans.begin(), ans.end()); return ans; } };
solution解法:
class Solution { public: string addStrings(string num1, string num2) { if (num1.size() < num2.size()) return addStrings(num2,num1); int i = num1.size() - 1;int j = num2.size() - 1;int carry = 0; for (;i>=0 && (j>=0 || carry);i--,j--){ int sum = num1[i] - '0' + (j>=0?num2[j] - '0':0) + carry; carry = sum / 10; sum = sum % 10; num1[i] = sum + '0'; } return carry?"1"+num1:num1; } };
401. Binary Wat
题意:二进制手表,前四位是小时位,后八位是分钟位,给定亮着的灯数,输出可能的时间字符串,小时不能有前导0,分钟必须两位
我的思路:bitset的使用,http://blog.csdn.net/qll125596718/article/details/6901935
我的代码:
class Solution { public: vector<string> readBinaryWatch(int num) { vector<string> ans; for (int i = 0; i < 12; i++) { bitset<4> h(i); for (int j = 0; j < 60; j++) { bitset<8> m(j); if (h.count()+m.count() == num) { ans.push_back(to_string(i)+(j < 10 ? ":0" : ":")+to_string(j)); } } } return ans; } };
solution解法:
class Solution { public: vector<string> readBinaryWatch(int num) { vector<string> rs; for (int h = 0; h < 12; h++) for (int m = 0; m < 60; m++) if (bitset<10>(h << 6 | m).count() == num) rs.emplace_back(to_string(h) + (m < 10 ? ":0" : ":") + to_string(m)); return rs; } };
386. Lexicographical Numbers
题意:按字典序输出1~n
我的思路:找规律
我的代码:
class Solution { public: vector<int> lexicalOrder(int n) { vector<int> ans; ans.push_back(1); for (int i = 1; i < n; i++) { if (ans[i-1]*10 <= n) ans.push_back(ans[i-1]*10); else if (ans[i-1]+1 <= n && ans[i-1]%10 != 9) ans.push_back(ans[i-1]+1); else if (ans[i-1]%10 == 9 || ans[i-1]+1 > n) { ans.push_back(ans[i-1]/10); while (ans[i]%10 == 9) ans[i] /= 10; ans[i]++; } } return ans; } };
solution解法:好一些
class Solution { public: vector<int> lexicalOrder(int n) { vector<int> res(n); int i = 1; for(int j = 0; j < n; j++){ res[j] = i; if(i * 10 <= n){ i *= 10; } else{ if(i >= n) i /= 10; i += 1; //cout<<i<<endl; while(i%10 == 0){ i /= 10; } } } return res; } };
417. Pacific Atlantic Water Flow
题意:每个位置能往上下左右不大于它的值的位置走,求能同时到达上、左边界和右、下边界的点
我的思路:从边界bfs
我的代码:
class Solution { public: const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; vector<pair<int, int>> pacificAtlantic(vector<vector<int>>& matrix) { vector<pair<int, int>> ans; if (matrix.size() == 0) return ans; int m = matrix.size(), n = matrix[0].size(); vector<vector<bool>> flag(m, vector<bool>(n, 0)), get(m, vector<bool>(n, 0)); queue<pair<int, int>> q; for (int i = 0; i < n; i++) { q.push(make_pair(0, i)); flag[0][i] = 1; } for (int i = 1; i < m; i++) { q.push(make_pair(i, 0)); flag[i][0] = 1; } while (!q.empty()) { int k = q.size(); for (int i = 0; i < k; i++) { pair<int, int> tmp = q.front(); q.pop(); for (int j = 0; j < 4; j++) { int x = tmp.first+dir[j][0], y = tmp.second+dir[j][1]; if (x >= 0 && x < m && y >= 0 && y < n && !flag[x][y] && matrix[x][y] >= matrix[tmp.first][tmp.second]) { q.push(make_pair(x, y)); flag[x][y] = 1; } } } } for (int i = 0; i < n; i++) { q.push(make_pair(m-1, i)); get[m-1][i] = 1; if (flag[m-1][i]) ans.push_back(make_pair(m-1, i)); } for (int i = 0; i < m-1; i++) { q.push(make_pair(i, n-1)); get[i][n-1] = 1; if (flag[i][n-1]) ans.push_back(make_pair(i, n-1)); } while (!q.empty()) { int k = q.size(); for (int i = 0; i < k; i++) { pair<int, int> tmp = q.front(); q.pop(); for (int j = 0; j < 4; j++) { int x = tmp.first+dir[j][0], y = tmp.second+dir[j][1]; if (x >= 0 && x < m && y >= 0 && y < n && !get[x][y] && matrix[x][y] >= matrix[tmp.first][tmp.second]) { q.push(make_pair(x, y)); get[x][y] = 1; if (flag[x][y]) ans.push_back(make_pair(x, y)); } } } } return ans; } };
419. Battleships in a Board
题意:给定一个二维board,问上边有多少“战舰”,战舰是1*N或者N*1的‘X’,两战舰之间至少隔着1个‘.’,即战舰不会相邻
我的思路:dfs,很差
我的代码:
class Solution { public: int dir[4][2] = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}}; void dfs(vector<vector<char>>& board,int x, int y) { board[x][y] = '.'; for (int i = 0; i < 4; i++) { int xx = x+dir[i][0], yy = y+dir[i][1]; if (xx >= 0 && xx < board.size() && yy >= 0 && yy < board[0].size() && board[xx][yy] == 'X') dfs(board, xx, yy); } } int countBattleships(vector<vector<char>>& board) { int ans = 0; for (int i = 0; i < board.size(); i++) for (int j = 0; j < board[0].size(); j++) if (board[i][j] == 'X') { ans++; dfs(board, i, j); } return ans; } };
九章最优解:找船头,即左边和上边都是‘.’的‘X’
class Solution { public: int countBattleships(vector<vector<char>>& board) { int len1 = board.size(); if(len1 == 0) return 0; int len2 = board[0].size(); int ans = 0; for(int i=0; i < len1; i++){ for(int j =0; j < len2; j++){ //船头的左边和上边一定不是‘X‘ if(board[i][j] == 'X' && (i == 0 || board[i-1][j] == '.') && (j == 0 ||board[i][j-1] == '.')){ ans ++; } } } return ans; } };
421. Maximum XOR of Two Numbers in an Array
题意:给定一组数,求最大的两个数的抑或值
我的思路:位运算
我的代码:
class Solution { public: int findMaximumXOR(vector<int>& nums) { int maxn = 0, mask = 0; for (int i = 31; i >= 0; i--) { mask |= (1<<i); unordered_set<int> s; for (int num: nums) s.insert(num&mask); int tmp = maxn|(1<<i); //就是每次再已有的的最大抑或值的基础上多置后边一位为1,看能不能抑或出来 for (int pre: s) if (s.find(pre^tmp) != s.end()) { maxn = tmp; break; } } return maxn; } };
423. Reconstruct Original Digits from English
题意:给定一个字符串,是英文数字,但是字母顺序是乱的,输出从小到大所有数字
我的思路:根据单词特征,先出02468个数再出13579个数
我的代码:
class Solution { public: string originalDigits(string s) { vector<int> let(26, 0), dig(10, 0); for (int i = 0; i < s.size(); i++) let[s[i]-'a']++; dig[0] = let['z'-'a']; let['o'-'a'] -= dig[0]; dig[2] = let['w'-'a']; let['o'-'a'] -= dig[2]; dig[4] = let['u'-'a']; let['o'-'a'] -= dig[4]; let['f'-'a'] -= dig[4]; dig[6] = let['x'-'a']; let['s'-'a'] -= dig[6]; let['i'-'a'] -= dig[6]; dig[8] = let['g'-'a']; let['i'-'a'] -= dig[8]; let['h'-'a'] -= dig[8]; dig[1] = let['o'-'a']; dig[3] = let['h'-'a']; dig[5] = let['f'-'a']; let['i'-'a'] -= dig[5]; dig[7] = let['s'-'a']; dig[9] = let['i'-'a']; string ans; for (int i = 0; i < 10; i++) while (dig[i]--) ans += i+'0'; return ans; } };
424. Longest Repeating Character Replacement
题意:有k次随意置换任意字符的机会,找出最长的重复字符的字符串。
我的思路:如果没有k的限制,让我们求把字符串变成只有一个字符重复的字符串需要的最小置换次数,那么就是字符串的总长度减去出现次数最多的字符的个数。如果加上k的限制,我们其实就是求满足(子字符串的长度减去出现次数最多的字符个数)<=k的最大子字符串长度即可
我的代码:
class Solution { public: int characterReplacement(string s, int k) { int i = 0, j = 0, maxn = 0, ans = 0; vector<int> num(26, 0); while (j < s.length()) { maxn = max(maxn, ++num[s[j]-'A']); while (j-i+1-maxn > k) --num[s[i++]-'A']; ans = max(ans, (j++)-i+1); } return ans; } };
434. Number of Segments in a String
水题
441. Arranging Coins
题意:给定一个数字n,问他能形成多少级完整的台阶(下一级比上一级多一个)
我的思路:二分
class Solution { public: int arrangeCoins(int n) { long long l = 1, r = n; while (l+1 < r) { long long mid = l+(r-l)/2; if ((mid+1)*mid/2 <= n) l = mid; else r = mid; } return (r+1)*r/2 > n ? l : r; } };
435. Non-overlapping Intervals
题意:给定一组区间,问最少去掉多少个可以没有重叠
我的思路:看代码把
class Solution { public: static bool cmp(const Interval& a, const Interval& b) { return a.end == b.end ? a.start<b.start : a.end<b.end; } int eraseOverlapIntervals(vector<Interval>& intervals) { if (intervals.size() == 0) return 0; sort(intervals.begin(), intervals.end(), cmp); int over = intervals[0].end, cnt = 1; for (int i = 0; i < intervals.size(); i++) if (intervals[i].start >= over) { cnt++; over = intervals[i].end; } return intervals.size()-cnt; } };
436. Find Right Interval
题意:给定一组区间,输出每个区间右边(开头大于等于结尾)最近一个区间的下标
我的思路:map+lower_bound
我的代码:
class Solution { public: vector<int> findRightInterval(vector<Interval>& intervals) { map<int, int> m; for (int i = 0; i < intervals.size(); i++) m[intervals[i].start] = i; vector<int> ans; for (int i = 0; i < intervals.size(); i++) { auto it = m.lower_bound(intervals[i].end); if (it == m.end()) ans.push_back(-1); else ans.push_back(it->second); } return ans; } };
438. Find All Anagrams in a String
题意:找出大串中与小串组成字母一样的子串首下标
我的思路:hash字母个数
我的代码:
class Solution { public: vector<int> findAnagrams(string s, string p) { vector<int> nump(26, 0), nums(26, 0); for (int i = 0; i < p.length(); i++) nump[p[i]-'a']++; vector<int> ans; for (int i = 0; i < s.length(); i++) { nums[s[i]-'a']++; if (i >= p.length()-1) { bool flag = 1; for (int i = 0; i < 26; i++) if (nump[i] != nums[i]) flag = 0; if (flag) ans.push_back(i-p.length()+1); nums[s[i-p.length()+1]-'a']--; } } return ans; } };
442. Find All Duplicates in an Array
题意:一个长度为n的数组包含数字1~n,有的只出现一次,有的出现两次,找出所有出现两次的数字,不能有额外空间,时间复杂度O(n)
我的思路:先扫一遍把元素换到他应该在的位置,再扫一遍不在自己位置的元素即出现了两次
我的代码:
class Solution { public: vector<int> findDuplicates(vector<int>& nums) { vector<int> ans; for (int i = 0; i < nums.size();) { if (nums[i] != i+1 && nums[i] != nums[nums[i]-1]) swap(nums[i], nums[nums[i]-1]); else i++; } for (int i = 0; i < nums.size(); i++) if (nums[i] != i+1) ans.push_back(nums[i]); return ans; } };
solution解法:将数字变负作为该位置已经有数的标记
class Solution { public: vector<int> findDuplicates(vector<int>& nums) { vector<int> duplicates; for(int i = 0; i < nums.size(); i++) { int j = abs(nums[i])-1; if(nums[j] < 0) duplicates.push_back(j+1); nums[j] = -nums[j]; } return duplicates; } };
443. String Compression
题意:字符串压缩,表示成几个某字符几个某字符的形式,1个不用写
我的思路:常规题
我的代码:
class Solution { public: int compress(vector<char>& chars) { chars.push_back('!'); int i = 1, cnt = 1, ans = 0, n = chars.size(); if (n == 2) return 1; while (i < n) { while (i < n && chars[i] == chars[i-1]) { cnt++; i++; } string tmp = to_string(cnt); chars[ans++] = chars[i-1]; if (cnt > 1) for (int k = 0; k < tmp.size(); k++) chars[ans++] = tmp[k]; cnt = 1; i++; } chars.resize(ans); return ans; } };
447. Number of Boomerangs
题意:求(i, j, k)数目,满足点i到点j和k的距离一样
我的思路:hash点的距离
我的代码:
class Solution { public: int dis(pair<int, int>& a, pair<int, int>& b) { return (a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second); } int numberOfBoomerangs(vector<pair<int, int>>& points) { int ans = 0, n = points.size(); unordered_map<int, int> m; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) if (i != j) { int d = dis(points[i], points[j]); if (m.find(d) != m.end()) ans += 2*m[d]++; else m[d] = 1; } m.clear(); } return ans; } };
448. Find All Numbers Disappeared in an Array
题意:题干跟上题一样,输出变为没有的数字
我的思路:上题的代码可以直接用
class Solution { public: vector<int> findDisappearedNumbers(vector<int>& nums) { vector<int> ans; for (int i = 0; i < nums.size();) { if (nums[i] != i+1 && nums[i] != nums[nums[i]-1]) swap(nums[i], nums[nums[i]-1]); else i++; } for (int i = 0; i < nums.size(); i++) if (nums[i] != i+1) ans.push_back(i+1); return ans; } };
452. Minimum Number of Arrows to Burst Balloons
题意:气球是水平线,给定首尾坐标,用直上的针扎破所有气球,求至少需要几根
我的思路:贪心,先按尾从小到大排,再排首,维护还未扎破的气球的最靠前的末尾,到下一个大于他的首,需要一根针
我的代码:
class Solution { public: static bool cmp(pair<int, int>& a, pair<int, int>& b) { return a.second == b.second ? a.first < b.first : a.second < b.second; } int findMinArrowShots(vector<pair<int, int>>& points) { if (points.size() == 0) return 0; sort(points.begin(), points.end(), cmp); int tail = points[0].second, ans = 0; for (int i = 1; i < points.size(); i++) if (points[i].first > tail) { ans++; tail = points[i].second; } return ans+1; } };
九章最优解:一样
453. Minimum Moves to Equal Array Elements
题意:每一步可以把一个数组的n-1个元素加一,求最少需要几步可以使数组元素都相等
我的思路:n-1个元素加一,相当于一个元素减1,所以只要找到最小的元素,求所有元素比他大多少求和即可
我的代码:
class Solution { public: int minMoves(vector<int>& nums) { int minn = nums[0], ans = 0; for (int i = 0; i < nums.size(); i++) if (nums[i] < minn) minn = nums[i]; for (int i = 0; i < nums.size(); i++) ans += nums[i]-minn; return ans; } };
九章最优解:棋差一着啊。。
class Solution { public: int minMoves(vector<int>& nums) { int sumNum = 0; int minNum = INT_MAX; for (int num : nums) { sumNum += num; minNum = min(minNum, num); } return sumNum - minNum * nums.size(); } };
454. 4Sum II
题意:有四个相同长度的数组,各取一个,问有多少种取法四个数之和为0
我的思路:两个数组,一个存前两个数组的n*n个和,另一个存另两个数组的和,将一个数组排序,利用lower_bound和upper_bound找另一个数组的负数
我的代码:
class Solution { public: int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) { int n = A.size(), ans = 0; vector<int> sum1, sum2; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { sum1.push_back(A[i]+B[j]); sum2.push_back(C[i]+D[j]); } sort(sum2.begin(), sum2.end()); for (int i = 0; i < n*n; i++) { int kl = lower_bound(sum2.begin(), sum2.end(), -sum1[i])-sum2.begin(); int kr = upper_bound(sum2.begin(), sum2.end(), -sum1[i])-sum2.begin(); ans += kr-kl; } return ans; } };
solution解法:
两个和数组都排序,从小往大找
class Solution { public: unsigned int partition(vector<int> &nums, int p, int r) { int x = nums[r],i=p-1; for (int j = p; j <= r - 1; ++j) { if (nums[j] <= x) { ++i; int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } } int temp = nums[i+1]; nums[i+1] = nums[r]; nums[r] = temp; return (i + 1); } vector<int>& quickSort(vector<int> &nums,int p,int r) { if (p < r) { unsigned int q = partition(nums, p, r); quickSort(nums, p, q - 1); quickSort(nums, q + 1, r); } return nums; } int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) { int i=0,j=0,k=0,n=A.size(),N=n*n; int ab[N+1], cd[N+1]; for(int i=0;i<n;++i){ for(int j=0;j<n;++j){ ab[k]=A[i]+B[j]; cd[k]=-C[i]-D[j]; ++k; } } ab[N] = INT_MAX; cd[N] = INT_MAX; sort(ab,ab+N); sort(cd,cd+N); int count =0; i=0,j=0; while((i<N)&&(j<N)){ if(ab[i]==cd[j]){ int u = 1, v = 1; while (ab[i] == ab[i + 1]) { u++; i++; } while (cd[j] == cd[j + 1]) { v++; j++; } count += u * v; ++i,++j; } else if(ab[i]>cd[j]){ ++j; } else ++i; } return count; } };
455. Assign Cookies
贪心水题
456. 132 Pattern
题意:判断数组中有没有ai, aj, ak such that i < j < k and ai < ak < aj.
我的思路:倒查,栈
我的代码:
class Solution { public: bool find132pattern(vector<int>& nums) { int s3 = 0x80000000; stack<int> s; for (int i = nums.size()-1; i >= 0 ; i--) { if (nums[i] < s3) return 1; else { while (!s.empty() && s.top() < nums[i]) { s3 = s.top(); s.pop(); } s.push(nums[i]); } } return 0; } };
459. Repeated Substring Pattern
题意:求字符串的循环节
我的思路:KMP
我的代码:
class Solution { public: void getnext(vector<int> &next, string s) { int i=0,j=-1; next[0]=-1; while(s[i]) { if(j==-1||s[i]==s[j]) { i++,j++; next[i]=j; } else j=next[j]; } for (int i = 0; i <= s.size(); i++) cout<<next[i]<<endl; } bool repeatedSubstringPattern(string s) { int n = s.size(); vector<int> next(n+1); getnext(next, s); return n%(n-next[n]) == 0 && next[n] != 0 ; } };
九章最优解:一样
461. Hamming Distance
题意:求两个数字的汉明距
我的思路:bitset
我的代码:
class Solution { public: int hammingDistance(int x, int y) { bitset<32> a(x), b(y); bitset<32> c = a^b; return c.count(); } };
九章最优解:
class Solution{ public: int hammingDistance(int x, int y) { int Distance = 0; while ( x != 0 || y != 0 ) { if ( x % 2 != y % 2) { Distance ++; } x /= 2; y /= 2; } return Distance; } }
solution解法:
class Solution { public: int hammingDistance(int x, int y) { int dist = 0; int XOR = x ^ y; while (XOR) { dist += XOR & 1; XOR >>= 1; } return dist; } };
462. Minimum Moves to Equal Array Elements II
题意:给定一数组,每步可以把一个元素加1或者减1,至少多少步能使所有元素相等
我的思路:求中位数
我的代码:
class Solution { public: int minMoves2(vector<int>& nums) { int n = nums.size(), ans = 0; sort(nums.begin(), nums.end()); for (int i = 0; i < n; i++) ans += abs(nums[i]-nums[n/2]); return ans; } };
九章最优解:一样
463. Island Perimeter
题意:给定一个二维数组,1表示陆地,只有一座小岛,求周长
我的思路:dfs
我的代码:
class Solution { public: int ans = 0; void dfs(vector<vector<int>>& grid, int x, int y, vector<bool> &flag) { flag[x*grid[0].size()+y] = 1; int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; for (int i = 0; i < 4; i++) { int xx = x+dir[i][0], yy = y+dir[i][1]; if (xx >= 0 && yy >= 0 && xx < grid.size() && yy < grid[0].size() && grid[xx][yy] == 1) { if (flag[xx*grid[0].size()+yy] == 0) dfs(grid, xx, yy, flag); } else ans++; } } int islandPerimeter(vector<vector<int>>& grid) { vector<bool> flag(grid.size()*grid[0].size(), 0); for (int i = 0; i < grid.size(); i++) for (int j = 0; j < grid[0].size(); j++) if (grid[i][j] == 1) { dfs(grid, i, j, flag); return ans; } } };
473. Matchsticks to Square
题意:判断一个数组中的数能否组成一个正方形
思路:discuss第一个
我的代码:
class Solution { public: static bool cmp(const int& a, const int& b) { return a > b; } bool dfs(vector<int> a, vector<int>& nums, int id, int k) { if (id == nums.size()) return (a[0] == a[1] && a[0] == a[2] && a[0] == a[3]); for (int i = 0; i < 4; i++) { if (a[i]+nums[id] > k) continue; int j = i; while (--j >= 0) if (a[i] == a[j]) break; if (j != -1) continue; a[i] += nums[id]; if (dfs(a, nums, id+1, k)) return 1; a[i] -= nums[id]; } return 0; } bool makesquare(vector<int>& nums) { int n = nums.size(); if (n < 4) return 0; sort(nums.begin(), nums.end(), cmp); int sum = 0; for (int i = 0; i < n; i++) sum += nums[i]; if (sum%4) return 0; vector<int> a(4, 0); return dfs(a, nums, 0, sum/4); } };
475. Heaters
题意:给定一个房间内的位置和火炉位置,求加热最小半径使火炉能加热所有位置
我的思路:找每个位置与最近的火炉的距离,最大距离即为所求
我的代码:
class Solution { public: int findRadius(vector<int>& houses, vector<int>& heaters) { sort(heaters.begin(), heaters.end()); int ans = 0; for (int i = 0; i < houses.size(); i++) { int da = lower_bound(heaters.begin(), heaters.end(), houses[i])-heaters.begin(), tmp = 0x7fffffff; if (da < heaters.size()) tmp = min(tmp, heaters[da]-houses[i]); if (da > 0) tmp = min(tmp, houses[i]-heaters[da-1]); ans = max(ans, tmp); } return ans; } };
476. Number Complement
题意:将给定数字的二进制(没有前导0)按位取反
我的思路:抑或1
我的代码:
class Solution { public: int findComplement(int num) { int yi = 1, n = num; while (n) { num ^= yi; yi <<= 1; n >>= 1; } return num; } };
solution解法:
class Solution { public: int findComplement(int num) { int pow = 1,res=0; unsigned int temp = ~num; while(pow < num && pow > 0){ if( temp != ((temp >> 1) <<1)) res += pow; temp >>= 1; //cout<<pow<<temp<<endl; pow <<= 1; } return res; } };
477. Total Hamming Distance
题意:求给定数组的数字间两两汉明距离之和
我的思路:数每一位的01之和
我的代码:
class Solution { public: int totalHammingDistance(vector<int>& nums) { int ans =0; for (int k = 0; k < 32; k++) { int num1 = 0; for (int i = 0; i < nums.size(); i++) { num1 += nums[i]&1; nums[i] >>= 1; } ans += num1*(nums.size()-num1); } return ans; } };
481. Magical String
题意:求串前n位有多少个1
我的思路:模拟串生成
我的代码:
class Solution { public: int magicalString(int n) { if (n <= 3) return n > 0; vector<int> s; s.push_back(1); s.push_back(2); s.push_back(2); int ans = 1, num = 2; while (s.size() < n) { for (int i = 0; i < s[num]; i++) s.push_back(num%2+1); if (num%2 == 0) ans += s[num]; num++; } if (s.size() > n && s[s.size()-1] == 1) ans -= 1; return ans; } };
482. License Key Formatting
题意:给定一个字符串和k,将字符串变成k个一组,用 - 隔开,不整除时第一段不一样
我的思路:简单题
我的代码:
class Solution { public: string licenseKeyFormatting(string S, int K) { string ans; int cnt = 0; for (int i = S.size()-1; i >= 0; i--) { if (S[i] == '-') continue; else { if (cnt%K == 0 && cnt > 0) ans += '-'; if (S[i] >= 'a' && S[i] <= 'z') S[i] += 'A'-'a'; ans += S[i]; cnt++; } } reverse(ans.begin(), ans.end()); return ans; } };
485. Max Consecutive Ones
题意:输出最长连续1的个数
我的思路:大水题
我的代码:
class Solution { public: int findMaxConsecutiveOnes(vector<int>& nums) { int ans = 0, tmp = 0; for (int i = 0; i < nums.size(); i++) { if (nums[i]) tmp++; else { ans = max(ans, tmp); tmp = 0; } } return max(ans, tmp); } };
491. Increasing Subsequences
题意:给定一数组,输出所有上升(不降)的子序列
我的思路:dfs+集合去重
我的代码:
class Solution { public: set<vector<int>> ans; void dfs(int f, vector<int>& nums, vector<int> s) { for (int i = f+1; i < nums.size(); i++) { if (nums[i] >= nums[f]) { vector<int> tmp = s; tmp.push_back(nums[i]); ans.insert(tmp); dfs(i, nums, tmp); while (nums[i] == nums[i+1]) i++; } } } vector<vector<int>> findSubsequences(vector<int>& nums) { for (int i = 0; i < nums.size(); i++) { vector<int> tmp; tmp.push_back(nums[i]); dfs(i, nums, tmp); } return vector<vector<int>> (ans.begin(), ans.end()); } };
492. Construct the Rectangle
题意:给一个数字,输出两个数乘积为它,且两个数差距最小
我的思路:从根号开始倒查
我的代码:
class Solution { public: vector<int> constructRectangle(int area) { vector<int> ans; for (int i = sqrt(area); i > 0; i--) if (area % i == 0) { ans.push_back(area/i); ans.push_back(i); return ans; } } };
solution解法:返回可以写为return {area/i, i};
495. Teemo Attacking
大水题
498. Diagonal Traverse
题意:将一个矩阵蛇形输出
我的思路:一个标记决定往右上走还是左下走,越界时改变坐标和标记状态
我的代码:
class Solution { public: vector<int> findDiagonalOrder(vector<vector<int>>& matrix) { if (matrix.size() == 0) return {}; int m = matrix.size(), n = matrix[0].size(), cnt = 0, i = 0, j = 0, flag = 0; int dir[2][2] = {{-1, 1}, {1, -1}}; vector<int> ans; while (cnt < m*n) { ans.push_back(matrix[i][j]); cnt++; int x = i+dir[flag%2][0], y = j+dir[flag%2][1]; if (x >= 0 && x < m && y >= 0 && y < n) { i = x; j = y; } else { if (y >= n) i++; else if (x >= m) j++; else if (y < 0) i++; else if (x < 0) j++; flag++; } } return ans; } };
503. Next Greater Element II
题意:给定一个数组视为循环的,输出每个数后边比他大的第一个数
我的思路:栈走两圈
我的代码:
class Solution { public: vector<int> nextGreaterElements(vector<int>& nums) { vector<int> ans(nums.size(), -1); stack<int> s; for (int i = 0; i < 2*nums.size(); i++) { while (!s.empty() && nums[s.top()] < nums[i%nums.size()]) { ans[s.top()] = nums[i%nums.size()]; s.pop(); } if (ans[i%nums.size()] == -1)s.push(i%nums.size()); } return ans; } };
504. Base 7
题意:写7进制,水题
506. Relative Ranks
题意:给定一个数组,输出各元素从大到小排序后的位次
我的思路:排序返回下标
我的代码:
class Solution { public: string num2str(int n) { string ret; while (n > 0) { ret += n%10+'0'; n /= 10; } reverse(ret.begin(), ret.end()); return ret; } template<typename T> vector<int> sort_indexes(const vector<T>& v) { vector<int> idx(v.size()); // initialize original index locations for (int i = 0; i != idx.size(); ++i) idx[i] = i; sort(idx.begin(), idx.end(), [& v](size_t i1, size_t i2) {return v[i1] > v[i2];}); // sort indexes based on comparing values in v return idx; } vector<string> findRelativeRanks(vector<int>& nums) { vector<string> ans(nums.size()); vector<int> idx = sort_indexes(nums); for (int i = 0; i < nums.size(); i++) { if (i == 0) ans[idx[i]] = "Gold Medal"; else if (i == 1) ans[idx[i]] = "Silver Medal"; else if (i == 2) ans[idx[i]] = "Bronze Medal"; else ans[idx[i]] = num2str(i+1); } return ans; } };
solution解法:语言不如人家
class Solution { public: vector<string> findRelativeRanks(vector<int>& nums) { int n=nums.size(); vector<string> ret(n, ""); vector<int> index(n, 0); for(int i=0; i<n; i++) index[i]=i; auto comp=[&nums](const int& a, const int& b) { return nums[a]>nums[b]; }; sort(index.begin(), index.end(), comp); for(int i=0; i<n; i++) { if(i==0) ret[index[i]]="Gold Medal"; else if(i==1) ret[index[i]]="Silver Medal"; else if(i==2) ret[index[i]]="Bronze Medal"; else ret[index[i]]=to_string(i+1); } return ret; } };
507. Perfect Number
题意:判断一个数是否等于出他自己以外的因子之和
我的思路:1~根号n找因子
我的代码:
class Solution { public: bool checkPerfectNumber(int num) { int sum = 0; for (int i = 2; i < sqrt(num); i++) if (num%i == 0) sum += i+(num/i); if (((int)sqrt(num))*((int)sqrt(num)) == num) sum += sqrt(num); return sum+1 == num; } };
solution解法:。。。
class Solution { public: bool checkPerfectNumber(int num) { return num==6 || num==28 || num==496 || num==8128 || num==33550336; } };
508. Most Frequent Subtree Sum
题意:输出出现频率最高的子树节点值之和
我的思路:dfs+map
我的代码:
class Solution { public: int dfs(TreeNode* root, map<int, int>& m, int& maxn) { if (!root) return 0; int ret = root->val; if (root->left) ret += dfs(root->left, m, maxn); if (root->right) ret += dfs(root->right, m, maxn); if (m.find(ret) != m.end()) m[ret]++; else m[ret] = 1; maxn = max(maxn, m[ret]); return ret; } vector<int> findFrequentTreeSum(TreeNode* root) { map<int, int> m; int maxn = 0; dfs(root, m, maxn); vector<int> ans; for (auto i: m) if (i.second == maxn) ans.push_back(i.first); return ans; } };
513. Find Bottom Left Tree Value
题意:输出最下层最左边节点的值
我的思路:bfs
我的代码:
class Solution { public: int findBottomLeftValue(TreeNode* root) { queue<TreeNode*> q; int ans; q.push(root); while (!q.empty()) { TreeNode* tmp = q.front(); ans = tmp->val; if (tmp->right) q.push(tmp->right); if (tmp->left) q.push(tmp->left); q.pop(); } return ans; } };
515. Find Largest Value in Each Tree Row
题意:给一棵树,返回每一行的最大值
我的思路:dfs
我的代码:
class Solution { public: void dfs(TreeNode* root, int layer, vector<int> &ans) { if (layer == ans.size()) ans.push_back(root->val); else ans[layer] = max(ans[layer], root->val); if (root->left) dfs(root->left, layer+1, ans); if (root->right) dfs(root->right, layer+1, ans); } vector<int> largestValues(TreeNode* root) { vector<int> ans; if (root == NULL) return ans; dfs(root, 0, ans); return ans; } };
solution解法:bfs
class Solution { public: vector<int> largestValues(TreeNode* root) { std::queue<TreeNode *> q; vector<int> res; if(!root) return res; q.push(root); while (!q.empty()) { int max = INT_MIN; for(int i = 0, n = q.size(); i < n; ++i) { TreeNode *node = q.front(); q.pop(); max = std::max(node->val, max); if(node->left) q.push(node->left); if(node->right) q.push(node->right); } res.push_back(max); } return res; } };
517. Super Washing Machines
题意:给定一组数,每一步可以选择任意个数向其左或右挪1,共需多少步可以使所有数字相等
我的思路:每台洗衣机每次只能移动一件衣服到邻接的洗衣机处,那么最小的移动次数将会与最多衣服的洗衣机有关。当拥有最多衣服的洗衣机不止一台时,此时需要找出达到平衡时需要移动最多步数的洗衣机。
我的代码:
class Solution { public: int findMinMoves(vector<int>& machines) { int sum = 0, n = machines.size(); for (int i = 0; i < n; i++) sum += machines[i]; if (sum%n) return -1; int t = sum/n, ans = 0, dir = 0; for (int i = 0; i < n; i++) { dir += machines[i]-t; ans = max(ans, max(machines[i]-t, abs(dir))); } return ans; } };
520. Detect Capital
题意:大水题
我的代码:
520. Detect Capitalclass Solution { public: bool detectCapitalUse(string word) { if (word.size() <= 1) return 1; int flag = 0; if (word[0] >= 'a' && word[0] <= 'z') flag = 1; for (int i = 1; i < word.size(); i++) { if (flag) { if (word[i] >= 'A' && word[i] <= 'Z') return 0; } else { if (i > 1 && (word[i]-95)*(word[i-1]-95) < 0) return 0; } } return 1; } };
522. Longest Uncommon Subsequence II
题意:求所有串的最大非公共子序列长度
我的思路:把所有串按长度从大到小排序,
523. Continuous Subarray Sum
题意:判断有没有连续的子串之和
我的思路:比较暴力,遍历所有子串和
我的代码:
class Solution { public: bool checkSubarraySum(vector<int>& nums, int k) { if (nums.size() <= 1) return 0; for (int i = 1; i < nums.size(); i++) nums[i] += nums[i-1]; nums.insert(nums.begin(), 0); for (int i = 2; i < nums.size(); i++) for (int j = 0; j <= i-2; j++) { if (k == 0 && nums[i] == nums[j] || k != 0 && (nums[i]-nums[j])%k == 0) return 1; } return 0; } };
solution解法:哈希余数
class Solution { public: bool checkSubarraySum(vector<int>& nums, int k) { if (k == 0) { for (int i=1; i<nums.size(); ++i) { if (nums[i]==0 && nums[i-1]==0) return true; } return false; } unordered_set<int> s; for (int i=0, sum=0; i<nums.size(); ++i) { sum += nums[i]; int mod = sum % k; if (s.find(mod) != s.end() || i>0 && mod==0) return true; s.insert(mod); } return false; } };
524. Longest Word in Dictionary through Deleting
题意:找出字典中最长的s串的子序列
我的思路:排序,双指针判断
我的代码:
class Solution { public: static bool cmp(const string& a, const string& b) { if (a.length() == b.length()) return a < b; return a.length() > b.length(); } string findLongestWord(string s, vector<string>& d) { string ans; sort(d.begin(), d.end(), cmp); for (int i = 0; i < d.size(); i++) { int l1 = 0, l2 = 0; while (l1 < s.length() && l2 < d[i].length()) { if (s[l1] == d[i][l2]) l2++; l1++; } if (l2 == d[i].length()) { ans = d[i]; break; } } return ans; } };
525. Contiguous Array
题意:给定一个01串,输出01个数相等的最长子串的长度
我的思路:若把0变成-1, 即可求和为0的最长子串长度,对和进行哈希
我的代码:
class Solution { public: int findMaxLength(vector<int>& nums) { map<int, int> f; int sum = 0, result = 0; f[0] = -1; for (int i = 0; i < nums.size(); i++) { if (nums[i] == 0) nums[i] = -1; sum += nums[i]; if (f.find(sum) != f.end()) result = max(result, i-f[sum]); else f[sum] = i; } return result; } };
526. Beautiful Arrangement
题意:给定n,求1~n有几种排列,使得第i位的元素整除i或者被i整除
我的思路:dfs
我的代码:
class Solution { public: void dfs(vector<int> tmp, int N, vector<bool> flag, int &ans) { if (tmp.size() == N) ans++; else { for (int i = 1; i <= N; i++) { if (flag[i] == 0 && (i%(tmp.size()+1) == 0 || (tmp.size()+1)%i == 0)) { tmp.push_back(i); flag[i] = 1; dfs(tmp, N, flag, ans); tmp.pop_back(); flag[i] = 0; } } } } int countArrangement(int N) { vector<bool> flag(N+1, 0); int ans = 0; for (int i = 1; i <= N; i++) { vector<int> tmp; tmp.push_back(i); flag[i] = 1; dfs(tmp, N, flag, ans); flag[i] = 0; } return ans; } };
solution解法:
class Solution { private: int arr[15] = {0}; int ans = 0; public: void helper(int N) { if(N==0) { ans++; return; } for(int i=0; i<N; i++) { if(N%arr[i]==0 || arr[i]%N==0) { swap(arr[i], arr[N-1]); helper(N-1); swap(arr[i], arr[N-1]); } } } int countArrangement(int N) { for(int i=0; i<N; i++) arr[i] = i+1; helper(N); return ans; } };
529. Minesweeper
题意:bfs水题
我的代码:
class Solution { public: const int dir[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}}; void bfs(vector<vector<char>>& board, int x, int y) { int cnt = 0; for (int i = 0; i < 8; i++) { int xx = x+dir[i][0], yy = y+dir[i][1]; if (xx >= 0 && xx < board.size() && yy >= 0 && yy < board[0].size() && board[xx][yy] == 'M') cnt++; } board[x][y] = cnt > 0 ? cnt+'0' : 'B'; if (cnt > 0) return; for (int i = 0; i < 8; i++) { int xx = x+dir[i][0], yy = y+dir[i][1]; if (xx >= 0 && xx < board.size() && yy >= 0 && yy < board[0].size() && board[xx][yy] == 'E') bfs(board, xx, yy); } } vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) { if (board[click[0]][click[1]] == 'M') { board[click[0]][click[1]] = 'X'; return board; } else { bfs(board, click[0], click[1]); } return board; } };
532. K-diff Pairs in an Array
题意:给定一个数组和k,求有多少个数对的绝对值之差为k
我的思路:set去重
我的代码:
class Solution { public: int findPairs(vector<int>& nums, int k) { if (k < 0) return 0; set<pair<int, int> > s; int n = nums.size(); for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if (nums[i]-nums[j] == k || nums[j]-nums[i] == k) s.insert(make_pair(max(nums[i], nums[j]), min(nums[i], nums[j]))); return s.size(); } };
solutoin解法:
class Solution { public: int findPairs(vector<int>& nums, int k) { if(k < 0) return 0; int size = nums.size(), res = 0; unordered_map<int, int> m; for(int i = 0; i < nums.size(); i++) { ++m[nums[i]]; } if(k != 0) { for(auto it = m.begin(); it != m.end(); it++) if(m.find(it->first + k) != m.end()) res++; } else { for(auto it = m.begin(); it != m.end(); it++) if(it->second > 1) res++; } return res; } };
537. Complex Number Multiplication
t题:复数乘法,大水题
539. Minimum Time Difference
题意:给定一组时间,输出最小的分钟差,最多20000个
我的思路:超过1440个必有重合,其他很常规
我的代码:
class Solution { public: int gg(string a, string b) { int h1 = 0, h2 = 0, m1 = 0, m2 = 0; for (int i = 0; i < 2; i++) { h1 = h1*10+a[i]-'0'; h2 = h2*10+b[i]-'0'; } for (int i = 3; i < 5; i++) { m1 = m1*10+a[i]-'0'; m2 = m2*10+b[i]-'0'; } if (m2 < m1) { m2 += 60; h2--; } if (h2 < h1) h2 += 24; h1 = (h2-h1)*60+m2-m1; return h1 <= 720 ? h1 : 1440-h1; } int findMinDifference(vector<string>& timePoints) { if (timePoints.size() > 1440) return 0; int minn = 2000; for (int i = 0; i < timePoints.size(); i++) for (int j = i+1; j < timePoints.size(); j++) { int timecha = gg(timePoints[i], timePoints[j]); minn = min(minn, timecha); } return minn; } };
540. Single Element in a Sorted Array
题意:输出有序数组中只出现一次的那个数自,时间复杂度O(n)
我的思路:二分
我的代码:
class Solution { public: int singleNonDuplicate(vector<int>& nums) { int l = 0, r = nums.size()-1; while (l+1 < r) { int mid = (l+r)/2; if (nums[mid] == nums[mid^1]) l = mid; else r = mid; } return nums[l] == nums[l^1] ? nums[r] : nums[l]; } };
class Solution { public: int singleNonDuplicate(vector<int>& nums) { int l = 0, r = nums.size()-1; while (l < r) { int mid = (l+r)/2; if (nums[mid] == nums[mid^1]) l = mid+1; else r = mid-1; } return nums[l];//== nums[l^1] ? nums[r] : nums[l]; } };
541. Reverse String II
题意:给定一字符串,每隔k个翻转k个
我的思路:水题
我的代码:
class Solution { public: string reverseStr(string s, int k) { int cnt = 1, i = 0; while (i < s.length()) { if (cnt%2) { if (i+k-1 < s.length()) reverse(s.begin()+i, s.begin()+i+k); else reverse(s.begin()+i, s.end()); } i += k; cnt++; } return s; } };
542. 01 Matrix
题意:给定一个01棋盘,把1全变为他与最近的0的距离
我的思路:bfs
我的代码:
class Solution { public: int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) { int m = matrix.size(), n = matrix[0].size(); queue<pair<int, int> > q; vector<vector<bool> > flag(m, vector<bool>(n)); int cnt = 1; for (int ii = 0; ii < m; ii++) for (int jj = 0; jj < n; jj++) flag[ii][jj] = 0; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) if (matrix[i][j] == 0) q.push(make_pair(i, j)); while(!q.empty()) { int k = q.size(); while (k--) { int x = q.front().first, y = q.front().second; for (int gg = 0; gg < 4; gg++) { int xx = x+dir[gg][0], yy = y+dir[gg][1]; if (xx >= 0 && xx < m && yy >= 0 && yy < n && flag[xx][yy] == 0 && matrix[xx][yy] > 0) { matrix[xx][yy] = cnt; flag[xx][yy] = 1; q.push(make_pair(xx, yy)); } } q.pop(); } cnt++; } return matrix; } };
543. Diameter of Binary Tree
题意:输出二叉树最远的两个节点间的距离
我的思路:经过某节点的最远距离是他左子树的最大深度加右子树的最大深度
我的代码:
class Solution { public: int maxn = 0; int maxdepth(TreeNode* root) { if (root->left == NULL && root->right == NULL) return 0; int k1 = root->left == NULL ? 0 : maxdepth(root->left)+1; int k2 = root->right == NULL ? 0 : maxdepth(root->right)+1; maxn = max(k1+k2, maxn); return max(k1, k2); } int diameterOfBinaryTree(TreeNode* root) { if (root) maxdepth(root); return maxn; } };
551. Student Attendance Record I
题意:大水题
553. Optimal Division
题意:给定一串数字,加除号和括号使得结果最大
我的思路:扯淡题
我的代码:
class Solution { public: string help(vector<int>& nums, int f, int flag) { if (nums.size()-f == 2) return to_string(nums[f])+'/'+to_string(nums[f+1]); if (flag) return to_string(nums[f])+"/("+help(nums, f+1, flag^1)+")"; return to_string(nums[f])+"/"+help(nums, f+1, flag); } string optimalDivision(vector<int>& nums) { if (nums.size() == 1) return to_string(nums[0]); return help(nums, 0, 1); } };
554. Brick Wall
题意:一行一行按砖块长度给定一面墙,问从哪儿下刀砍到的砖块最少
我的思路:hash砖块沿的位置,沿最多的那列砍下去砖块最少
我的代码:
class Solution { public: int leastBricks(vector<vector<int>>& wall) { if (wall.size() == 0) return 0; map<int, int> cnt; for (int i = 0; i < wall.size(); i++) { int sum = 0; for (int j = 0; j < wall[i].size()-1; j++) { sum += wall[i][j]; if (cnt.find(sum) != cnt.end()) cnt[sum]++; else cnt[sum] = 1; } } int maxn = 0; map<int,int>::iterator it = cnt.begin(); while (it != cnt.end()) { maxn = max(it->second, maxn); it++; } return wall.size()-maxn; } };
556. Next Greater Element III
题意:给定一个数字,输出由相同数字组成的大于他的下一个数字,若超int或者没有输出-1
我的思路:知道next_permutation函数就很睡了
我的代码:
class Solution { public: int s2num(string s) { int ret = 0; for (int i = 0; i < s.size(); i++) ret = ret*10+s[i]-'0'; return ret; } int nextGreaterElement(int n) { string s = to_string(n); next_permutation(s.begin(), s.end()); int m = s2num(s); return m > n ? m : -1; } };
557. Reverse Words in a String III
大水题
560. Subarray Sum Equals K
题意:给定一个数组,求有多少个和为k的连续子串
我的思路:hash
我的代码:
class Solution { public: int subarraySum(vector<int>& nums, int k) { map<int, int> m; int ans = 0; nums.insert(nums.begin(), 0); m[0] = 1; for (int i = 1; i < nums.size(); i++) { nums[i] += nums[i-1]; if (m.find(nums[i]-k) != m.end()) ans += m[nums[i]-k]; if (m.find(nums[i]) != m.end()) m[nums[i]]++; else m[nums[i]] = 1; } return ans; } };
561. Array Partition I
题意:大水题
565. Array Nesting
大水题
566. Reshape the Matrix
大水题
567. Permutation in String
题意:判断s2串中有没有s1的排列
我的思路:暴力左右s2的与s1长度相同的子串
我的代码:
class Solution { public: bool checkInclusion(string s1, string s2) { if (s2.size() < s1.size()) return 0; vector<int> cnt1(26, 0);// cnt2(26, 0); for (int i = 0; i < s1.size(); i++) cnt1[s1[i]-'a']++; for (int i = 0; i <= s2.size()-s1.size(); i++) { vector<int> cnt2(26, 0); for (int j = 0; j < s1.size(); j++) cnt2[s2[i+j]-'a']++; for (int j = 0; j < 26; j++) { if (cnt2[j] != cnt1[j]) break; if (j == 25) return 1; } } return 0; } };
solution解法:
class Solution { public: bool checkInclusion(string s1, string s2) { int count[256]; for(int i = 0; i < 256; i++) count[i]=0; for(int i = 0; i < s1.size(); i++) count[s1[i]]--; for(int l = 0, r = 0; r < s2.size(); r++) { if (++count[s2[r]] > 0) while(--count[s2[l++]] != 0); else if ((r - l + 1) == s1.size()) return true; } return s1.size() == 0; } };
575. Distribute Candies
大水题
581. Shortest Unsorted Continuous Subarray
题意:求数组中只要排好多长一段子数组就可以整体有序
我的思路:跟怕拍好的对比、
我的代码:
class Solution { public: int findUnsortedSubarray(vector<int>& nums) { vector<int> sorted(nums); sort(sorted.begin(), sorted.end()); int i = 0, j = nums.size()-1; while (i < nums.size() && sorted[i] == nums[i]) i++; while (j >= 0 && sorted[j] == nums[j]) j--; return j-i+1 > 0 ? j-i+1 : 0; } };
solution解法:
class Solution { public: int findUnsortedSubarray(vector<int>& nums) { int start = 0; int end = -1; int minVal = INT_MAX; int maxVal = INT_MIN; for (int i = 0; i < nums.size(); ++i) { if (maxVal > nums[i]) { end = i; } else { maxVal = nums[i]; } } for (int i = nums.size() - 1; i >= 0; --i) { if (minVal < nums[i]) { start = i; } else { minVal = nums[i]; } } return end - start + 1; } };
592. Fraction Addition and Subtraction
题意:分数加减法
我的思路:模拟
我的代码:
class Solution { public: int gcd(int a, int b) { return b == 0 ? a : gcd(b, a%b); } string fractionAddition(string expression) { vector<int> num(2, 0); int ope = 0, i = 0, j = 0, fenmu = 1, fenzi = 0; if (expression[0] == '-') j = 1; while (i < expression.size()) { if (expression[i] == '+') ope = 0, j++; else if (expression[i] == '-') ope = 1, j++; else if (expression[i] == '/') j++; else { if (expression[i] == '1' && i+1 < expression.size() && expression[i+1] == '0') num[j%2] = 10, i++; else num[j%2] = expression[i]-'0'; if (j%2) { int gongyin = gcd(fenmu, num[1]); fenzi *= num[1]/gongyin; num[0] *= fenmu/gongyin; if (ope) fenzi -= num[0]; else fenzi += num[0]; fenmu = num[1]*fenmu/gongyin; } } i++; } string ans; int gongyin = fenzi == 0 ? 1 : gcd(fenzi, fenmu); if (gongyin < 0) gongyin = -gongyin; if (fenzi == 0) fenmu = 1; ans += to_string(fenzi/gongyin); ans += '/'; ans += to_string(fenmu/gongyin); return ans; } };
593. Valid Square
题意:给四个点判正方形
我的思路:模拟
我的代码:
class Solution { public: bool validSquare(vector<int>& p1, vector<int>& p2, vector<int>& p3, vector<int>& p4) { vector<int> v12(2), v34(2), v13(2), v14(2); v12[0] = p1[0]-p2[0]; v12[1] = p1[1]-p2[1]; v34[0] = p3[0]-p4[0]; v34[1] = p3[1]-p4[1]; v13[0] = p1[0]-p3[0]; v13[1] = p1[1]-p3[1]; v14[0] = p1[0]-p4[0]; v14[1] = p1[1]-p4[1]; if (v12[0] == 0 && v12[1] == 0 || v34[0] == 0 && v34[1] == 0 || v13[0] == 0 && v13[1] == 0 || v14[0] == 0 && v14[1] == 0) return 0; if (v12[0] == v34[0] && v12[1] == v34[1]) { vector<int> v23(2); v23[0] = p2[0]-p3[0]; v23[1] = p2[1]-p3[1]; if (v12[0]*v13[0]+v12[1]*v13[1] == 0 && v14[0]*v23[0]+v14[1]*v23[1] == 0) return 1; } else if (v12[0] == -v34[0] && v12[1] == -v34[1]) { vector<int> v24(2); v24[0] = p2[0]-p4[0]; v24[1] = p2[1]-p4[1]; if (v12[0]*v14[0]+v12[1]*v14[1] == 0 && v13[0]*v24[0]+v13[1]*v24[1] == 0) return 1; } else if (v12[0]*v34[0]+v12[1]*v34[1] == 0) { vector<int> v23(2); v23[0] = p2[0]-p3[0]; v23[1] = p2[1]-p3[1]; if (v13[0]*v14[0]+v13[1]*v14[1] == 0) return 1; } return 0; } };
solution解法:。。。
class Solution { public: bool validSquare(vector<int>& p1, vector<int>& p2, vector<int>& p3, vector<int>& p4) { vector<int> vect; vect.push_back(dist(p1, p2)); vect.push_back(dist(p1, p3)); vect.push_back(dist(p1, p4)); vect.push_back(dist(p2, p3)); vect.push_back(dist(p2, p4)); vect.push_back(dist(p3, p4)); sort(vect.begin(), vect.end()); if((vect[0] == vect[1]) && (vect[0] == vect[2]) && (vect[0] == vect[3]) && (vect[0]*2 == vect[4]) && (vect[4] == vect[5]) && vect[0] != 0) { return true; }else { return false; } } int dist(vector<int>& a, vector<int>& b) { return (a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]); } };
594. Longest Harmonious Subsequence
题意:给定一个数组,输出元素差值为1的子串的长度
我的思路:hash,记录每个数字出现次数
我的代码:
class Solution { public: int findLHS(vector<int>& nums) { if (nums.size() == 0) return 0; map<int, int> m; int ans = 0; for (int i = 0; i < nums.size(); i++) { if (m.find(nums[i]) != m.end()) m[nums[i]]++; else m[nums[i]] = 1; } map<int, int>::iterator it = m.begin(); for (int i = 0; i < m.size(); i++, it++) if (m.find((it->first)+1) != m.end()) ans = max(ans, it->second+m[(it->first)+1]); return ans; } };
soluiton解法:排序,再算个数
class Solution { public: int findLHS(vector<int>& nums) { if (nums.empty()) return 0; std::sort(nums.begin(), nums.end()); int max = 0; int len0 = 0; int len1 = 0; int num0 = nums[0]-2; int num1 = nums[0]; for (int i=0; i<nums.size(); i++){ if (nums[i] == num1) len1++; else { if (num1-num0 == 1) max = std::max(max, len0+len1); if (nums[i] == num1+1){ len0 = len1; } else { len0 = 0; } num0 = num1; len1 = 1; num1 = nums[i]; } } if (num1-num0 == 1) max = std::max(max, len0+len1); return max; } };
598. Range Addition II
大水题
605. Can Place Flowers
水题
class Solution { public: bool canPlaceFlowers(vector<int>& flowerbed, int n) { int maxn = 0, tmp = 1; for (int i = 0; i < flowerbed.size(); i++) { if (flowerbed[i] == 0) tmp++; else { maxn += (tmp-1)/2; tmp = 0; } } maxn += tmp/2; return maxn >= n; } };
611. Valid Triangle Number
题意:在数组中找出所有能组成三角形的数字组合数目
我的思路:先排序,由较小的两边找最大的那边
我的代码:
class Solution { public: int triangleNumber(vector<int>& nums) { int n = nums.size(), ans = 0; sort(nums.begin(), nums.end()); for (int i = 0; i < n-2; i++) for (int j = i+1; j < n-1; j++) ans += lower_bound(nums.begin()+j+1, nums.end(), nums[i]+nums[j])-nums.begin()-j-1; return ans; } };
621. Task Scheduler
题意:给定一串字符,将其重排,每两个一样的字符中间必须有n个其他的或者占位符,求重排后最小长度
我的代码:都没想明白就过了。。
class Solution { public: int leastInterval(vector<char>& tasks, int n) { vector<int> num(26, 0); for (int i = 0; i < tasks.size(); i++) num[tasks[i]-'A']++; int maxn = 0, cnt = 0; for (int i = 0; i < 26; i++) if (num[i] >= maxn) { if (num[i] == maxn) cnt++; else { maxn = num[i]; cnt = 1; } } cout<<cnt<<endl; return max((maxn-1)*(n+1)+cnt, (int)tasks.size()); } };
628. Maximum Product of Three Numbers
题意:输出一个数组最大的三数乘积
我的思路:排序
我的代码:
class Solution { public: int maximumProduct(vector<int>& nums) { sort(nums.begin(), nums.end()); int n = nums.size(); return max(nums[0]*nums[1]*nums[n-1], nums[n-1]*nums[n-2]*nums[n-3]); } };
solution解法:只找5个值 ,不排序
class Solution { public: int maximumProduct(vector<int>& nums) { int p1 = INT_MIN, p2 = INT_MIN, p3 = INT_MIN; int n1 = INT_MAX, n2 = INT_MAX; for(int i = 0; i<nums.size(); i++){ if (nums[i]>=p1){ p3 = p2; p2 = p1; p1 = nums[i]; } else if(nums[i]>=p2){ p3 = p2; p2 = nums[i]; } else if(nums[i]>p3) p3 = nums[i]; if(nums[i]<=n1){ n2 = n1; n1 = nums[i]; } else if(nums[i]<n2) n2 = nums[i]; } return max(p1*p2*p3, p1*n1*n2); } };
633. Sum of Square Numbers
题意:判断一个数能否写成两个整数的平方和
我的思路:水题
我的代码:
class Solution { public: bool judgeSquareSum(int c) { for (int i = 0; i <= (int)sqrt(c/2); i++) { int n = c-i*i; if ((int)sqrt(n)*sqrt(n) == n) return 1; } return 0; } };
645. Set Mismatch
题意:数组1~n中有一个数字确实并且一个重复,找出这两个数字
我的思路:集合查重,抑或得缺失
我的代码:
class Solution { public: vector<int> findErrorNums(vector<int>& nums) { vector<int> ans; int xxor = 0; unordered_set<int> s; for (int i = 0; i < nums.size(); i++) { xxor ^= i+1; xxor ^= nums[i]; if (s.find(nums[i]) != s.end()) ans.push_back(nums[i]); s.insert(nums[i]); } ans.push_back(xxor^ans[0]); return ans; } };
discuss解法:
public static int[] findErrorNums(int[] nums) { int[] res = new int[2]; for (int i : nums) { if (nums[Math.abs(i) - 1] < 0) res[0] = Math.abs(i); else nums[Math.abs(i) - 1] *= -1; } for (int i=0;i<nums.length;i++) { if (nums[i] > 0) res[1] = i+1; } return res; }
647. Palindromic Substrings
题意:求回文子串数目,收尾下标不同即视为不同子串
我的思路:查询奇偶数目的回文串
我的代码:
class Solution { public: int countSubstrings(string s) { int ans = 0; for (int i = 0; i < s.length(); i++) { for (int j = 0; i-j >= 0 && i+j < s.length() && s[i-j] == s[i+j]; j++) ans++; for (int j = 0; i-j >= 0 && i+1+j < s.length() && s[i-j] == s[i+1+j]; j++) ans++; } return ans; } };
667. Beautiful Arrangement II
题意:输出数组1~n,使得前后数字差的绝对值正好k个数字
我的思路:给定n
那么k最大为n-1
,假设这k
个数字是 n-1,n-2,n-3...1
,所以数列可以是1,n-1,2,n-2,....
,比如给定n=9 k=8
则数列可以是1 9 2 8 3 7 6 4 5
,可以看出这组数据差值是8 7 6 5 4 3 2 1
,如果给定k<n-1
,则将剩余的项用递增或者递减顺序即可。
我的代码:
class Solution { public: vector<int> constructArray(int n, int k) { int i = 1, j = n, cnt = 0; vector<int> ans; while (cnt < k-1 && i <= j) { if (cnt%2) ans.push_back(j--); else ans.push_back(i++); cnt++; } while (i <= j && cnt%2) ans.push_back(j--); while (i <= j && cnt%2 == 0) ans.push_back(i++); return ans; } };
670. Maximum Swap
题意:将一个数字的两位最多交换一次使得输出的数字最大
我的思路:跟从大到小排序的顺序比较,遇到不一样的时候交换
我的代码:
class Solution { public: static bool cmp(const char& a, const char& b) { return a > b; } int maximumSwap(int num) { string str = to_string(num), str2 = str; unordered_map<char, int> m; for (int i = 0; i < str.size(); i++) m[str[i]] = i; sort(str.begin(), str.end(), cmp); for (int i = 0; i < str.size(); i++) if (str[i] != str2[i]) { swap(str2[i], str2[m[str[i]]]); break; } return atoi(str2.c_str()); } };
678. Valid Parenthesis String
题意:给定一组小括号和星号,星号可以看作左或右或没有,判断能否合法
思路: https://www.cnblogs.com/grandyang/p/7617017.html
我的代码:
class Solution { public: bool checkValidString(string s) { stack<int> l, x; for (int i = 0; i < s.length(); i++) { if (s[i] == '(') l.push(i); else if (s[i] == '*') x.push(i); else { if (l.empty() && x.empty()) return 0; else if (!l.empty()) l.pop(); else x.pop(); } } while (!l.empty() && !x.empty()) { if (l.top() > x.top()) return 0; l.pop(); x.pop(); } return l.empty(); } };