最后一块石头的重量
每一回合,从中选出两块最重的石头,然后将它们一起粉碎。假设石头的重量分别为 x
和 y
,且 x <= y
。那么粉碎的可能结果如下:
- 如果
x == y
,那么两块石头都会被完全粉碎; - 如果
x != y
,那么重量为x
的石头将会完全粉碎,而重量为y
的石头新重量为y-x
。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0
。
提示:
1 <= stones.length <= 30
1 <= stones[i] <= 1000
class Solution { public int lastStoneWeight(int[] stones) { PriorityQueue<Integer> pq = new PriorityQueue<>((s1,s2)->(s2-s1)); for(int stone:stones) { pq.offer(stone); } while(pq.size()>1) { int i = pq.poll(); int j = pq.poll(); if(i>j) pq.offer(i-j); } if(pq.size()==1) return pq.peek(); else return 0; } }
删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S
,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:"abbaca" 输出:"ca" 解释: 例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
提示:
1 <= S.length <= 20000
S
仅由小写英文字母组成。
class Solution { public String removeDuplicates(String S) { return core(S,0,S.length()-1); } public String core(String S, int begin, int end) { for(int i=begin;i<end;i++) { if(S.charAt(i)==S.charAt(i+1)) { String now = S.substring(begin,i)+S.substring(i+2,end+1); //System.out.println(now); return core(now,0,now.length()-1); } } return S; } }
最长字符串链
给出一个单词列表,其中每个单词都由小写英文字母组成。
如果我们可以在 word1
的任何地方添加一个字母使其变成 word2
,那么我们认为 word1
是 word2
的前身。例如,"abc"
是 "abac"
的前身。
词链是单词 [word_1, word_2, ..., word_k]
组成的序列,k >= 1
,其中 word_1
是 word_2
的前身,word_2
是 word_3
的前身,依此类推。
从给定单词列表 words
中选择单词组成词链,返回词链的最长可能长度。
示例:
输入:["a","b","ba","bca","bda","bdca"] 输出:4 解释:最长单词链之一为 "a","ba","bda","bdca"。
提示:
1 <= words.length <= 1000
1 <= words[i].length <= 16
words[i]
仅由小写英文字母组成。class Solution { public: bool canChange(string& s1, string& s2) { int len1 = s1.length(); int len2 = s2.length(); if(len1+1!=len2) return false; int i=0; int j=0; while(j<len2) { if(s1[i]==s2[j]) { ++i; ++j; } else { ++j; if(j-i>1) { return false; } } } return true; } int longestStrChain(vector<string>& words) { int n = words.size(); vector<vector<int>> g(n, vector<int>(n, 0)); sort(words.begin(), words.end(), [](string& w1, string& w2) { return w1.length()<w2.length(); } ); for(int i = 0; i < n; ++i) { for(int j = i+1; j < n; ++j) { if(canChange(words[i], words[j])) { g[i][j] = 1; } } } vector<int> lcnt(n, 1); for(int i=0;i<n;++i) { for(int j=0;j<i;++j) { if(g[j][i]) { int tmp = lcnt[j]+1; lcnt[i] = max(tmp, lcnt[i]); } } } return *max_element(lcnt.begin(), lcnt.end()); } };
最后一块石头的重量 II
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x
和 y
,且 x <= y
。那么粉碎的可能结果如下:
如果 x == y
,那么两块石头都会被完全粉碎;
如果 x != y
,那么重量为 x
的石头将会完全粉碎,而重量为 y
的石头新重量为 y-x
。
最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0
。
示例:
输入:[2,7,4,1,8,1] 输出:1 解释: 组合 2 和 4,得到 2,所以数组转化为 [2,7,1,8,1], 组合 7 和 8,得到 1,所以数组转化为 [2,1,1,1], 组合 2 和 1,得到 1,所以数组转化为 [1,1,1], 组合 1 和 1,得到 0,所以数组转化为 [1],这就是最优值。
提示:
1 <= stones.length <= 30
1 <= stones[i] <= 1000
class Solution { public: int lastStoneWeightII(vector<int>& stones) { int diff[101][30001]={0}; int sum = 0; int n = stones.size(); for(int i=0;i<n;++i) { sum+=stones[i]; } diff[0][stones[0]] = 1; for(int i=1;i<n;++i) { for(int j=0;j<=sum;++j) { if(diff[i-1][j]) { diff[i][j+stones[i]] = 1; diff[i][abs(j-stones[i])] = 1; } } } for(int i = 0; i <= sum; ++i) { if(diff[n-1][i]) { return i; } } return 0; } };