[总结] letcode

372 阅读2分钟

指引

前序:最近打算刷一波算法题,奈何坚持不下来,感觉是方法不对;现在重新调整,按照类型来刷,顺便记录一下刷题过程,加油!!!

刷题步骤:

一、基本操作

  • length属性:用于获取数组长度
  • length()方法:用于获取字符串长度
  • size()方法:用于获取泛型集合有多少个元素

1、str.charAt(i)的意思是第i个字符在字符串str中所占的位置返回值:

String s = 'AAAAA11DSF';
char c = s.charAt(1);
int aa = s.length() 
String aa = s.substring(i, i+2) 
s.indexOf(AA); 索引开始位置 : 0

List<String> output = new ArrayList<String>();

--------------------------
char[] str1 = s.toCharArray();
char[] str2 = t.toCharArray();
Arrays.sort(str1);
Arrays.sort(str2);
return Arrays.equals(str1, str2);

2、对字符串的使用:

StringBuilder stringBuilder = new StringBuilder()   ;
stringBuilder.append(romans[index] + " ");

3、栈-后进先出

Stack<Character> stack = new Stack<Character>();
stack.pop();
stack.push(c); 
stack.isEmpty()

peek 不改变栈的值(不删除栈顶的值),
pop 会把栈顶的值删除。

4、deque双端队列

 Deque<Character> deque = new LinkedList<>();
 deque.addFirst(123);
 deque.addLast(234);
 deque.removeLast(111);
 deque.getLast();

5、queue队列,先进先出

4、hash

HashMap<Character, Character> mappings = new HashMap<Character, Character>(); 
mappings.put(')', '(');
mappings.containsKey(c)

  全是知识点

        Map<String, List> ans = new HashMap<String, List>();
        for (String s : strs) {
            char[] ca = s.toCharArray();
            Arrays.sort(ca);
            String key = String.valueOf(ca);
            if (!ans.containsKey(key)) ans.put(key, new ArrayList());
            ans.get(key).add(s);
        }
        return new ArrayList(ans.values());

5、List

数组转list
List<String> skuIdList = Arrays.asList("".split(","));

排序,无返回值
Arrays.sort("".split(","));

6、HashMap

两个map相等用equals

7、Queue

  Queue<String> queue = new LinkedList<String>();   
  queue.offer("a");  // 添加元素
  TreeNode node = q.poll(); //取出元素

8、链表

 LinkedList<Integer> list = new LinkedList<>();
 list.add(node.val); //按顺序加到后面 
 list.addFirst(node.val); //加到开始位置,为了倒序         

--------------------------------------------------------------------------------

  1.   String   str.length()

  2.   char[] result = str.toCharArray();    int length = result.length;

  3.    StringBuffer aaaa = new StringBuffer(); aaaa.toString()

  4. Arrays.sort(arr); int``[] arr

  5. int``max = Math.max(max, continuousLength);

二、二分查询

1、什么样的题型需要二分?

  • 时间复杂度是logn
  • 升序数组

2、模版框架

注意:对于有目标值的题目有target,可以有相等模式即基本方法,其他的需要构造比较函数

最基本的二分查找算法

int binary_search(int[] nums, int target) {
    int left = 0, right = nums.length - 1; 
    while(left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1; 
        } else if(nums[mid] == target) {
            // 直接返回
            return mid;
        }
    }
    // 直接返回
    return -1;
}
-------------------------------------------------------------
寻找左侧边界的二分查找

int left_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 别返回,锁定左侧边界
            right = mid - 1;
        }
    }
    // 最后要检查 left 越界的情况
    if (left >= nums.length || nums[left] != target) {        return -1;
    }
    return left;
}

---------------------------------------------------------------
寻找右侧边界的二分查找

int right_bound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] == target) {
            // 别返回,锁定右侧边界
            left = mid + 1;
        }
    }
    // 最后要检查 right 越界的情况
    if (right < 0 || nums[right] != target) {        return -1;
    }
    return right;
}

三、滑动窗口

1、这个算法技巧的思路,就是维护一个窗口,不断滑动,然后更新答案

2、通用框架

 public String minWindow(String s, String t) {
        if(t.length() > s.length()){
            return "";
        }
        HashMap<Character,Integer> need = new HashMap<>();
        HashMap<Character,Integer> window = new HashMap<>();

        for(int i=0;i< t.length();i++){
            char ww = t.charAt(i);
            need.put(ww,need.getOrDefault(ww,0)+1);
        }

        int left = 0;int right = 0;int valid = 0;
        int start = 0; int len = Integer.MAX_VALUE;
        while(right< s.length()){
            char aa = s.charAt(right);
            right++;
            if(need.containsKey(aa)){
                window.put(aa,window.getOrDefault(aa,0)+1);
                if(need.get(aa).equals(window.get(aa)) ){
                    valid++;
                }
            }

            while(valid == need.size()){
                if(right - left < len){
                    start = left;
                    len = right-left;
                }
                char bb = s.charAt(left);
                left++;
                if (need.containsKey(bb)){
                    if (window.get(bb).equals(need.get(bb))) {
                        valid--;
                    }
                    window.put( bb, window.get( bb ) - 1 ); 
                }
            }
        }
        return len == Integer.MAX_VALUE ? "":s.substring( start, start+len );
    }

四、双指针

1、两数之和/三数之和/四数之和

模版:

  • 1、先数组排序 

  • 2、如果是:三个数相加,有一层for循环;四数相加,有两层循环

  • 3、while判断

        Arrays.sort(nums);
        for (int i = 0; i < nums.length-2; i++) {            
            int left = i+1;
            int right = nums.length-1;
            while(m < n){
                int sum = nums[i] + nums[left]+ nums[right];
                if(sum == 0){
                 }  else if(sum > 0){
                 }  else {}
            }
         }
    
    /**
     * 三数之和
     */
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        if(nums == null || nums.length <3){
            return result;
        }
        Arrays.sort(nums);
        int ns = nums.length;
        for (int i = 0; i < ns-2; i++) {
            int m = i+1;
            int n = nums.length-1;
            if(nums[i]>0){
                break;
            }
            if(i>0 && nums[i] == nums[i-1]){
                continue;
            }
            while(m < n){
                int sum = nums[i] + nums[m]+ nums[n];
                if(sum == 0){
                    result.add(Arrays.asList(nums[i],nums[m],nums[n]));
                    while(m<n && nums[m]== nums[m+1]){    m++;}
                    while(m<n&& nums[n] == nums[n-1]){    n--;}
                    m++;n--;
                } else if(sum > 0){
                    while(m<n&& nums[n] == nums[n-1]){    n--; }
                    n--;
                } else if(sum < 0){
                    while(m<n && nums[m]== nums[m+1]){    m++;}
                    m++;
                }
            }
        }
        return result;
    }
    
    /**
     * 四数之和 
     */
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>>  res = new ArrayList<>();
        if(nums == null || nums.length <4){
            return res;
        }
        Arrays.sort(nums);
        int n = nums.length;
        for(int i= 0; i< n-3;i++){
            if(i>0 && nums[i]==nums[i-1]){
                continue;
            }
            for(int j = i+1;j< n-2;j++){
                if(j>i+1 && nums[j] == nums[j-1]){
                    continue;
                }
                int left = j+1;
                int right = n-1;
                while(left < right){
                    int sum = nums[i]+nums[j]+nums[left]+nums[right];
                    if(sum == target){
           res.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
                        while(left < right && nums[left] == nums[++left]);
                        while(left < right && nums[right] == nums[--right]);
                    }else if(sum > target){
                        while(left < right && nums[right] == nums[--right]);
                    }else if (sum < target){
                        while(left < right && nums[left] == nums[++left]);
                    }
                }
            }
        }
        return res;
    }
    

2、双指针--快慢指针

五、二叉树

1、前序遍历

2、从前序和中序遍历序列构造二叉树

3、二叉树的层序遍历(齿形)

4、二叉树的深度

5、平衡树

平衡树是二叉搜索树和堆合并构成的数据结构,它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

二叉树的深度

-----------------------------------------------------------------------------------

二、链表

1、17 题搞定 BAT 面试——链表题

2、neo4j 节点属性在单向链表上

1、链表基础

2、链表反转方法2

3、链表是否有环

4、图解链表

三、大顶堆/小顶堆

1、总结篇 :大顶堆和小顶堆 重点总结,包括从2亿数据中找10个最小的数

小顶堆:队列默认自然顺序排列,小顶堆,不必重写compare

PriorityQueue pq = new PriorityQueue<>();

大顶推:

PriorityQueue left = new PriorityQueue<>(Comparator.reverseOrder()); 

PriorityQueue Bbb = new PriorityQueue<>((x, y) -> (y - x));