394. 字符串解码(中等)
思路:递归调用一个编码方法
class Solution {
public String decodeString(String s) {
return coding(1,s);
}
public String coding(int k,String s){
StringBuilder sb = new StringBuilder();
StringBuilder temp = new StringBuilder();
boolean flag = false; // 标记是否在括号里
int tk = 0;
int lk = 0;
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
if(!flag){
if(c=='[')
flag = true;
else if(c>='0'&&c<='9'){
int cnt = 0;
while(s.charAt(i+cnt)>='0'&&s.charAt(i+cnt)<='9'){
cnt++;
}
tk = Integer.parseInt(s.substring(i,i+cnt));
if(s.charAt(i+cnt)=='['){
flag = true;
i +=cnt;
}
}else{
sb.append(c);
}
}else{
if(c=='[')
lk++;
else if(c==']'&&lk==0){
sb.append(coding(tk,temp.toString()));
tk = 0;
temp.setLength(0);
flag = false;
continue;
}else if(c==']')
lk--;
temp.append(c);
}
}
String st = sb.toString();
for(int i=1;i<k;i++)sb.append(st);
return sb.toString();
}
}
503. 下一个更大元素 II(中等)
// 思路:单调栈 + 循环数组
class Solution {
public int[] nextGreaterElements(int[] nums) {
Stack<Integer> sta = new Stack<>();
int max = nums[0];
int id = 0;
int res[] = new int[nums.length];
for(int i=0;i<nums.length;i++){
if(nums[i]>max){
max = nums[i];
id = i;
}
}
sta.push(max);
res[id] = -1;
for(int i=(id-1+nums.length)%nums.length;i!=id;i=(i-1+nums.length)%nums.length){
if(nums[i]<sta.peek()){
res[i] = sta.peek();
}else if(nums[i]==max){
res[i] = -1;
}else{
while(!sta.isEmpty() && sta.peek()<=nums[i])sta.pop();
if(!sta.isEmpty())res[i] = sta.peek();
else res[i] = max;
}
sta.push(nums[i]);
}
return res;
}
}
54. 螺旋矩阵(中等)
// 思路:定义一个方向,如果走不动了就换方向
// 还要定义一个 visit,访问过的不要访问
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
List<Integer> res = new ArrayList<>();
boolean visit[][] = new boolean[n][m];
int direct[][] = new int[][]{{0,1},{1,0},{0,-1},{-1,0}};
int i=0,j=-1,cnt=0,d=0;
while(cnt<m*n){
int last = d;
boolean flag = true;
while(i+direct[d][0]<0|| i+direct[d][0]>=n ||
j+direct[d][1]<0|| j+direct[d][1]>=m ||
visit[i+direct[d][0]][j+direct[d][1]]){
d = (d+1)%4;
if(d==last){
flag = false;
break;
}
}
if(!flag)break;
i = i+direct[d][0];
j = j+direct[d][1];
visit[i][j] = true;
res.add(matrix[i][j]);
cnt++;
}
return res;
}
}
763. 划分字母区间(中等)
// 维护一个区间对象,按照起始节点排序,
// 如果start < end0 && end > end0 -> end = end0
// 如果start > end0 截断
class Solution {
public List<Integer> partitionLabels(String s) {
int edge[][] = new int[26][2];
for(int i=0;i<26;i++)edge[i][0]=-1;
List<Integer> res = new ArrayList<>();
for(int i=0;i<s.length();i++){
if(edge[s.charAt(i)-'a'][0] == -1) edge[s.charAt(i)-'a'][0] = i;
edge[s.charAt(i)-'a'][1] = i;
}
Arrays.sort(edge,Comparator.comparingInt(a->a[0]));
int id = 0;
while(edge[id][0]==-1)id++;
int start = edge[id][0],end = edge[id][1];
for(int i=id+1;i<edge.length;i++){
if(edge[i][0]>end){
res.add(end-start+1);
start = edge[i][0];
end = edge[i][1];
}else {
end = Math.max(end,edge[i][1]);
}
}
res.add(end-start+1);
return res;
}
}
90. 子集 II(中等)
思路:之前的思路是在搜索的过程中把字节添加进去,现在的思路是每次遇到一个元素,问你要不要,要几个,相同元素问一次,选择 0-n 个
// 思路:把元素和出现的次数统计起来,每次判断的时候,直接判断每个元素出现几次即可,0-n 次
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
int mp[] = new int[21];
for(int num:nums)mp[num+10]++;
dfs(res,mp,0,new ArrayList<>());
return res;
}
public void dfs(List<List<Integer>> res,int[] mp,int it,List<Integer> tp){
int id = it+1, m = mp.length;
if(it == mp.length){
res.add(new ArrayList<>(tp));
return;
}
while(id<m && mp[id]==0)id++;
dfs(res,mp,id,tp);
for(int i=0;i<mp[it];i++){
tp.add(it-10);
dfs(res,mp,id,tp);
}
for(int i=0;i<mp[it];i++){
tp.remove(tp.size()-1);
}
}
}
剑指 Offer 34. 二叉树中和为某一值的路径(113. 路径总和 II)(中等)
class Solution {
public boolean isBalanced(TreeNode root) {
return dfs(root);
}
public boolean dfs(TreeNode root){
if(root==null)return true;
return Math.abs(height(root.left)-height(root.right))<=1 && dfs(root.left) && dfs(root.right);
}
public int height(TreeNode root){
if(root==null)return 0;
int left = height(root.left);
int right = height(root.right);
return Math.max(left,right)+1;
}
}
剑指 Offer II 062. 实现前缀树(中等)
class Trie {
class Node{
public Node children[];
private boolean isWord;
public Node(){
this.children = new Node[26];
this.isWord = false;
}
}
public Node root;
/** Initialize your data structure here. */
public Trie() {
this.root = new Node();
}
/** Inserts a word into the trie. */
public void insert(String word) {
Node current = this.root;
for(char c:word.toCharArray()){
Node child = current.children[c-'a'];
if(child==null){
child = new Node();
current.children[c-'a'] = child;
}
current = child;
}
current.isWord = true;
}
/** Returns if the word is in the trie. */
public boolean search(String word) {
Node current = this.root;
for(char c:word.toCharArray()){
Node child = current.children[c-'a'];
if(child==null)return false;
current = child;
}
return current.isWord;
}
/** Returns if there is any word in the trie that starts with the given prefix. */
public boolean startsWith(String prefix) {
Node current = this.root;
for(char c:prefix.toCharArray()){
Node child = current.children[c-'a'];
if(child==null)return false;
current = child;
}
return true;
}
}