算法记录|笔试中遇到的题

394. 字符串解码

在这里插入图片描述
我自己写的方法

class Solution {
    public String decodeString(String s) {
        char[] chs = s.toCharArray();
        LinkedList<Character> stack = new LinkedList<>();

        for(char ch:chs){
            if(ch==']'){
            stack = helper(stack);
            }else{
                stack.push(ch);
            }
        }

        //stack变成字符串
        String str ="";

        while(!stack.isEmpty()){
          str = stack.pop()+str;
        }
        return str;

    }

    public  LinkedList<Character> helper( LinkedList<Character> stack){
       ArrayList<Character> list = new ArrayList<>();
       while(stack.peek()!='['){
           list.add(stack.pop());
       }
       stack.pop();
      //取数字
     String a="";
      while(!stack.isEmpty()&&stack.peek()>='0'&&stack.peek()<='9'){
          a = stack.pop()+a;
      }
      int ans = Integer.parseInt(a);


       for(int i=0;i<ans;i++){
         for(int j = list.size()-1;j>=0;j--){
             stack.push(list.get(j));
         }
       }

       return stack;
    }
}

730.统计不同回文子序列

在这里插入图片描述

3. 无重复字符的最长子串

在这里插入图片描述

方法一:滑动窗口
视频解析:

class Solution {
     public int lengthOfLongestSubstring(String s){
       char[] chs = s.toCharArray();
       int n = chs.length;
       int left =0; 
       int right =0;
       int length=0;
       int maxlen =0;

       HashSet<Character> set = new  HashSet<>();
       while(right<n){
      //右指针没有存放在set中
         if(!set.contains(chs[right])){
            set.add(chs[right]);
            right++;
            length++;
            maxlen = Math.max(length,maxlen);

         }else{
         //右指针的元素已存放在set中,需要不断移动左指针
           while(set.contains(chs[right])){
             set.remove(chs[left]);
             left++;
             length--;
           }
           //直到set中不存在右指针的元素
          set.add(chs[right]);
            right++;
            length++;
         }
       }
       return maxlen;
     }
}



/// 上面的方法简化
class Solution {
     public int lengthOfLongestSubstring(String s){
       char[] chs = s.toCharArray();
       int n = chs.length;
       int left =0;
       int right =0;
       int length=0;
       int maxlen =0;

       HashSet<Character> set = new  HashSet<>();
       while(right<n){
         
           while(set.contains(chs[right])){
             set.remove(chs[left]);
             left++;
             length--;
           }
          set.add(chs[right]);
            right++;
            length++;
             maxlen = Math.max(length,maxlen);
         }
       
       return maxlen;
     }
}

滑动窗口的模板
和上面简化的方法是同一个模板了哈
在这里插入图片描述

方法二
都是固定右指针,移动左指针,但是这个方法移动得更快一些

class Solution {
     public int lengthOfLongestSubstring(String s){
       char[] chs = s.toCharArray();
       int n = chs.length;
       int left =0;
       int right =0;
       int length=0;

       HashMap<Character,Integer> map = new HashMap<>();
       for(int i=0;i<n;i++){
           if(map.containsKey(chs[i])){
              left = Math.max(left,map.get(chs[i])+1);
           }
           map.put(chs[i],i);
           length = Math.max(length,i-left+1);
       }
       return length;
     }
}

76.最小覆盖子串

在这里插入图片描述

class Solution {
    public String minWindow(String s, String t) {
        int[] have = new int[128];
        int[] need = new int[128];

    if(s ==null||s == null|| s==""||t ==""){
        return "";
    }

        for(char c:t.toCharArray()){
            need[c]++;
        }

        int left =0;
        int right=0;
        int minlen = s.length()+1;
        int count =0;
        int start =left;

        while(right<s.length()){
            char ch = s.charAt(right);

           // 对右边的节点的处理
             if(need[ch]==0){
                 right++;
                continue;
            }

            if(have[ch]<need[ch]){
                  count++; 
                }
                have[ch]++;
               right++;

                while(count == t.length()){
                    //开始移动左边
                if(right-left<minlen){
                    minlen = right-left;
                    start = left;
                }
                char l = s.charAt(left);
                if(need[l]==0){
                    left++;
                    continue;
                }
                if(have[l] == need[l]){
                   count--;
                }
                have[l]--;
                 left++;
                }
            }

        if( minlen == s.length()+1){
            return "";
        }

        return s.substring(start,start+ minlen);

        }
}

316. 去除重复字母(单调栈)

代码来自于这个链接

class Solution {
    public String removeDuplicateLetters(String s) {
     
     int[] nums = new int[26];
     boolean[] visited = new boolean[26];

     char[] chs = s.toCharArray();

     for(char ch:chs){
         nums[ch-'a']++;
     }

     LinkedList<Character> stack = new LinkedList<>();

    for(int i=0;i<chs.length;i++){
      char ch = chs[i];
      nums[ch-'a']--;

      if(visited[ch-'a']) continue;

      while(!stack.isEmpty()&&stack.peek()>ch&&nums[stack.peek()-'a']>0){
         visited[stack.peek()-'a']=false;
         stack.pop();
      }
      stack.push(ch);
      visited[ch-'a'] = true;

    }

    StringBuilder sb = new StringBuilder();

    while(!stack.isEmpty()){
        sb.append(stack.pop()) ;
    }
  return sb.reverse().toString();

    }
}

1636. 按照频率将数组升序排序(优先队列-大根堆)

类似于347. 前 K 个高频元素

在这里插入图片描述

class Solution {
    public int[] frequencySort(int[] nums) {

    HashMap<Integer,Integer> map = new  HashMap<>();
    PriorityQueue<int[]> queue = new  PriorityQueue<>((o1,o2)->o1[1]!=o2[1]?o1[1]-o2[1]:o2[0]-o1[0]);
   
 for(int num :nums){
     map.put(num,map.getOrDefault(num,0)+1);
 }

  for(Map.Entry<Integer,Integer> entry:map.entrySet()){
         queue.add(new int[]{entry.getKey(),entry.getValue()});
    }

    int index =0;
    int[] cur = new int[2];
    while(!queue.isEmpty()){
     cur= queue.poll();
    
     for(int j=0;j<cur[1];j++){
         nums[index] = cur[0];
         index++;
     }
    }
    
    return nums;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值