20240504
394.字符串编码
1.栈
时间复杂度和空间复杂度O(n)
class Solution {
int ptr;
public String decodeString(String s) {
LinkedList<String> stk=new LinkedList<String>();
ptr=0;
while(ptr<s.length()){
char cur=s.charAt(ptr);
if(Character.isDigit(cur)){
String digits=getDigits(s);
stk.addLast(digits);
}else if(Character.isLetter(cur)||cur=='['){
stk.addLast(String.valueOf(s.charAt(ptr++)));
}else{
++ptr;
LinkedList<String> sub=new LinkedList<String>();
while(!"[".equals(stk.peekLast())){
sub.addLast(stk.removeLast());
}
Collections.reverse(sub);
stk.removeLast();
int repTime=Integer.parseInt(stk.removeLast());
StringBuffer t=new StringBuffer();
String o=getString(sub);
while(repTime-->0){
t.append(o);
}
stk.addLast(t.toString());
}
}
return getString(stk);
}
public String getDigits(String s){
StringBuffer ret=new StringBuffer();
while(Character.isDigit(s.charAt(ptr))){
ret.append(s.charAt(ptr++));
}
return ret.toString();
}
public String getString(LinkedList<String> v){
StringBuffer ret=new StringBuffer();
for(String s:v){
ret.append(s);
}
return ret.toString();
}
}
2.递归法
分解为子问题
class Solution {
public String decodeString(String s) {
return dfs(s,0)[0];
}
private String[] dfs(String s,int i){
StringBuilder res=new StringBuilder();
int multi=0;
while(i<s.length()){
if(s.charAt(i)>='0'&&s.charAt(i)<='9'){
multi=multi*10+Integer.parseInt(String.valueOf(s.charAt(i)));
}
else if(s.charAt(i)=='['){
String[] tmp=dfs(s,i+1);
i=Integer.parseInt(tmp[0]);
while(multi>0){
res.append(tmp[1]);
multi--;
}
}
else if(s.charAt(i)==']')
return new String[]{String.valueOf(i),res.toString()};
else
res.append(String.valueOf(s.charAt(i)));
i++;
}
return new String[]{res.toString()};
}
}
20240505
1046.最后一块石头的重量
每一次给数组分组,从最后位置开始比较
public int lastStoneWeight(int[] stones) {
int index=stones.length-1;
for(int i=0;i<stones.length-1;i++){
Arrays.sort(stones);
if(stones[index-1]==0) break;
stones[index]-=stones[index-1];
stones[index-1]=0;
}
return stones[index];
}
java中优先队列,就是堆
public int lastStoneWeight(int[] stones) {
PriorityQueue<Integer> pq=new PriorityQueue<>((a,b)->b-a);
for(int x:stones){
pq.offer(x);
}
while(pq.size()>1){
int y=pq.poll();
int x=pq.poll();
if(x!=y){
pq.offer(y-x);
}
}
return pq.size()==1?pq.poll():0;
}
20240506
209.长度最小的子数组
public int minSubArrayLen(int target, int[] nums) {
int n=nums.length;
int ans=n+1;
int sum=0;
int left=0;
for(int right=0;right<n;right++){
sum+=nums[right];
while(sum-nums[left]>=target){
sum-=nums[left++];
}
if(sum>=target){
ans=Math.min(ans,right-left+1);
}
}
return ans<=n?ans:0;
}
20240508
541.反转字符串II
时间和空间复杂度都是O(n)
public String reverseStr(String s, int k) {
char[] cs = s.toCharArray();
int n = s.length();
for (int l = 0; l < n; l = l + 2 * k) {
int r = l + k - 1;
reverse(cs, l, Math.min(r, n - 1));
}
return String.valueOf(cs);
}
void reverse(char[] cs, int l, int r) {
while (l < r) {
char c = cs[l];
cs[l] = cs[r];
cs[r] = c;
l++; r--;
}
}
557.反转字符串中的单词III
class Solution {
public String reverseWords(String s) {
char[] array=s.toCharArray();
int start=0;
for(int i=0;i<array.length;i++){
if(array[i]==' '){
reverse(array,start,i-1);
start=i+1;
continue;
}
if(i==array.length-1){
reverse(array,start,i);
}
}
return new String(array);
}
private void reverse(char[] array,int l,int r){
while(l<r){
char temp=array[l];
array[l]=array[r];
array[r]=temp;
l+=1;
r-=1;
}
}
}
151.反转字符串中的单词
时间空间复杂度都是O(n)
public String reverseWords(String s) {
s=s.trim();
int j=s.length()-1,i=j;
StringBuilder res=new StringBuilder();
while(i>=0){
while(i>=0&&s.charAt(i)!=' ') i--;
res.append(s.substring(i+1,j+1)+" ");
while(i>=0&&s.charAt(i)==' ') i--;
j=i;
}
return res.toString().trim();
}
459.重复的子字符串
1.枚举,时间O(n的平方),空间O(1)
public boolean repeatedSubstringPattern(String s) {
int n=s.length();
for(int i=1;i*2<=n;++i){
if(n%i==0){
boolean match=true;
for(int j=i;j<n;++j){
if(s.charAt(j)!=s.charAt(j-i)){
match=false;
break;
}
}
if(match){
return true;
}
}
}
return false;
}
2.kmp匹配算法
时间空间O(n)
class Solution {
public boolean repeatedSubstringPattern(String s) {
return kmp(s+s,s);
}
public boolean kmp(String query,String pattern){
int n=query.length();
int m=pattern.length();
int[] fail=new int[m];
Arrays.fill(fail,-1);
for(int i=1;i<m;++i){
int j=fail[i-1];
while(j!=-1&&pattern.charAt(j+1)!=pattern.charAt(i)){
j=fail[j];
}
if(pattern.charAt(j+1)==pattern.charAt(i)){
fail[i]=j+1;
}
}
int match=-1;
for(int i=1;i<n-1;++i){
while(match!=-1&&pattern.charAt(match+1)!=query.charAt(i)){
match=fail[match];
}
if(pattern.charAt(match+1)==query.charAt(i)){
++match;
if(match==m-1){
return true;
}
}
}
return false;
}
}