leetcode

leetcode

two pointers

在这里插入图片描述

反向双指针

反转字符串344

解:

class Solution {
    public char[] reverseString(char[] s) {
        int i = 0 ;
        int j = s.length -1;

        while(i< j){
           char temp = s[i];
            s[i] = s[j];
            s[j] = temp;
            i++;
            j--;
        }
        return s;

    }
}
盛最多水的容器11

解:

class Solution {
    public int maxArea(int[] height) {
    int l =0, r =height.length-1, result =0;
    // 套用反向公式
    while (l<r){
       int tempResult = (Math.min(height[l],height[r])*(r-l));
        result = Math.max(result,tempResult);
        // 如果L 小说明 L+1 ~R 积水可能比L~R积水大
        if(height[l]<= height[r]){
            l ++;
        }else{
            r--;
        }
    }
    return result;

    }
}
接雨水 42

解:

class Solution {
    public int trap(int[] height) {
        int l = 0;
        int r = height.length-1;
        int leftMax =0;
        int rightMax =0;
        int result =0;
        while (l<r){
        // 这部分右边比左边大 所以只考虑左边最大值即可
            if(height[l]< height[r]){
                leftMax = Math.max(leftMax,height[l]);
                result = result + (leftMax-height[l]);
                l++;
            }else{
                 rightMax = Math.max(rightMax,height[r]);
                 result = result + (rightMax-height[r]);
                r--;
            }

        }
       return result;


    }
}

总结


在这里插入图片描述

同向双指针

如果想要数据的相对位置保持不变 那就只能用同向

删除有序数组中的重复项26

解:

class Solution {
    public int removeDuplicates(int[] nums) {
        int i =0;
        int j= 0;
        while (j<nums.length){
            if(i == 0 || nums[j] != nums[i-1]){
                nums[i++] = nums[j++];
            }else{
             j++;
            }
        }
        return i;

    }
}
删除有序数组中的重复项 II 80

解:

class Solution {
    public int removeDuplicates(int[] nums) {
        int len = nums.length;
        if(len<=2){
            return len;
        }
        int l =2, r= 2;
        while (r <nums.length){
            if(nums[r]!= nums[l-2]){
                nums[l++] = nums[r++];
            }else{
             r++;
            }
        }
        return l;

    }
    
}
移动零 283

解:

class Solution {
    public void moveZeroes(int[] nums) {
        int n = nums.length, left = 0, right = 0;
        while (right < n) {
            if (nums[right] != 0) {
                swap(nums, left, right);
                left++;
            }
            right++;
        }
    }

    public void swap(int[] nums, int left, int right) {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }
}

删除字符串中的所有相邻重复项 1047

解:

class Solution {
    public String removeDuplicates(String s) {
        char [] str = s.toCharArray();
        int i=0,j=0;
        while(j<str.length){
            str[i] = str[j];
            if(i>0 && str[i] == str[i-1]){
                i--;
            }else{
                i++;
            }

            j++;

        }
        return new String(str,0,i);

    }
}

在这里插入图片描述

binary search

常用于排好序的array 时间复杂度是 o(logN)

基础二分查找

在这里插入图片描述

二分查找 704
class Solution {
    public int search(int[] nums, int target) {
        int i = 0, j = nums.length -1;
        while(i<=j){
          int mid = i+(j-i)/2;
            if(target == nums[mid] ){
                return mid;
            }else if(target > nums[mid] ){
                i = mid+1;
            }else{
                j = mid-1;
            } }
       return -1;
    }}
在排序数组中查找元素的第一个和最后一个位置 34
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int len = nums.length;
        if(len == 0){
            return new int [] {-1,-1};
        }

        int fistPosition = findFirstPosition(nums,target);
        if(fistPosition == -1){
            return new int[] {-1,-1};
        }
        int lastPosition = findLastPosition(nums,target);
        return new int[]{fistPosition,lastPosition};


    }

    public int findFirstPosition(int[] nums, int target){
        int left = 0;
        int right = nums.length-1;
        //退出这个循环一定是 left = right
        while (left < right){
            int mid = left+ (right-left)/2;
            if (nums[mid] < target ){
                left = mid+1;
            }else if(nums[mid] == target){
                right = mid;
            }else if (nums[mid] >target){
                right = mid-1;
            }
        }
        if (nums[left] == target){
            return left;
        }
            return -1;
    }

    public int findLastPosition(int[] nums, int target){
        int left = 0;
        int right = nums.length-1;
        //退出这个循环一定是 left = right
        while (left < right){
            // 防止出现死循环
            int mid = left+ (right-left+1)/2;
            if (nums[mid] < target ){
                left = mid+1;
            }else if(nums[mid] == target){
                left = mid;
            }else if (nums[mid] >target){
                right = mid-1;
            }
        }
        if (nums[left] == target){
            return left;
        }
        return -1;
    }

}

查找有序数组中最接近k的值
class Solution {
    public int findClosestNumber(int[] nums) {
        int i = 0, j = nums.length -1;
        while(i< j-1){
            int mid = i+(j-i)/2;
            if(target > nums[mid] ){
                i = mid;
            }else{
                j = mid;
            }
         } 
         //数组会剩下两个数据
        if(target > nums[j]){
            return nums[j];
        }else if(target < nums[i]){
            return nums[i];
        }
        else {
            return target-nums[i] >= nums[j]-target ? nums[j]:nums[i];
        }
    }
}

在这里插入图片描述

进阶二分查找

山脉数组的峰顶索引 852
class Solution {
    public int peakIndexInMountainArray(int[] arr) {
        int left = 0,right = arr.length-1;
        while(left<=right){
            int mid = left + (right - left)/2;
            if(arr[mid]>arr[mid+1]&& arr[mid]>arr[mid-1]){
                return mid;
                }
            if(arr[mid]>arr[mid+1]){
                left = mid;
            }
            else{
                right = mid;
            }
        }
        return -1;
    }
    
}
在 D 天内送达包裹的能力 1011
class Solution {
    public int shipWithinDays(int[] weights, int days) {
        int left = Arrays.stream(weights).max().getAsInt(), right = Arrays.stream(weights).sum();
        while (left < right){
            int mid = left + (right - left)/2;
            int need = 1, currentWeight = 0;
            for(int weight:weights){
                if(currentWeight + weight > mid){
                ++need;
                currentWeight = 0;
                } 
                currentWeight += weight;
            }
            
            if(need <= days){
                right = mid;
            }else {
                left = mid+1;
            }
        }
        return left;
    }
}

Linked List

链表中倒数第k个节点
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode i = head, j = head;
        for(int c = 0 ;c<k ; c++){
            j = j.next;
        }
        while (j != null){
            i = i.next;
            j = j.next;
        }
    return i;
    }
}
反转链表
 // 循环解法
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode currentNode = head;
        while(currentNode!= null){
            //先把要断开的节点赋值给一个临时变量
            ListNode tempNode = currentNode.next;
            //改变指针指向
            currentNode.next = pre;
            // 赋值 pre和 currentNode
            pre = currentNode;
            currentNode = tempNode;
        }
        return pre;
    }
    //递归解法
    public ListNode reverseList(ListNode head) {
        return reverse(null,head);
    }

    private static ListNode reverse(ListNode pre,ListNode cur){
        if(cur==null) return pre;
        ListNode next = cur.next;
        cur.next = pre;
        return reverse(cur,next);
    }

stack

在这里插入图片描述

Stack.peek()
peek()函数返回栈顶的元素,但不弹出该栈顶元素。
Stack.pop()
pop()函数返回栈顶的元素,并且将该栈顶元素出栈。
每日温度 739
class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int len = temperatures.length;
        //默认元素0
        int [] res = new int[temperatures.length];
        Deque<Integer> stack  = new ArrayDeque<Integer>();
        for (int i = 0; i < temperatures.length ; i++ ){
            while(!stack.isEmpty() && temperatures[i]> temperatures[stack.peek()] ){
                int index =  stack.pop();
                res[index] = i-index;
            }
            stack.push(i);
        }
        return  res;
    }
}
行星碰撞 735
class Solution {
    public int[] asteroidCollision(int[] asteroids) {
        Deque<Integer> stack =  new ArrayDeque<>();
        for(int asteroid : asteroids){
            // 无论左边的星球是正是负 他俩都不会相撞
            if(asteroid > 0){
                stack.push(asteroid);
            }else{
                // 三种情况 当前数据为负数
                // 栈顶元素为正,且比当前元素绝对值小  可能会存在多条这样的数据所以用while
                while (!stack.isEmpty()&& stack.peek() > 0 && stack.peek()< -asteroid){
                    stack.pop();
                }
                // 栈顶元素为正 且 相加为0
                if(!stack.isEmpty()&& stack.peek() == -asteroid){
                    stack.pop();
                }else if(stack.isEmpty() || stack.peek() < 0){
                    stack.push(asteroid);
                } 
            }
        }
       int [] res = new int[stack.size()];
       for(int i = stack.size()-1; i>=0; i--){
           res[i] = stack.pop();
       }
       return res;

    }
}
有效的括号 20
class Solution {
    public boolean isValid(String s) {
        int n = s.length();
        if (n % 2 == 1) {
            return false;
        }

        Map<Character, Character> pairs = new HashMap<Character, Character>();
        pairs.put(')', '(');
        pairs.put(']', '[');
        pairs.put('}', '{');
        Deque<Character> stack = new LinkedList<Character>();
        for (int i = 0; i < n; i++) {
            char ch = s.charAt(i);
            if (pairs.containsKey(ch)) {
                if (stack.isEmpty() || stack.peek() != pairs.get(ch)) {
                    return false;
                }
                stack.pop();
            } else {
                stack.push(ch);
            }
        }
        return stack.isEmpty();
    }
}

在这里插入图片描述

heap

在这里插入图片描述

数组中的第K个最大元素215
//沙雕解法
class Solution {
    public int findKthLargest(int[] nums, int k) {
        Arrays.sort(nums);
        return nums[nums.length - k];
    }
}
//正经解法
class Solution {
    public int findKthLargest(int[] nums, int k) {
        //初始化定义最小堆
        PriorityQueue<Integer> heap = new PriorityQueue<>();
        //遍历数组 如果遇到比堆顶大的数字 则加进堆中
        for ( int num:nums) {
          //  如果不带 = 就是不包含重复数字
            if(heap.size()< k || heap.peek() <= num){
                //添加元素
                heap.offer(num);
            }
            if(heap.size()>k){
                // 拿出堆顶元素
                heap.poll();
            }
        }
        return  heap.peek();
    }
}


在这里插入图片描述

合并K个升序链表 23
 public static  ListNode mergeKLists(ListNode[] lists) {

        //创建一个堆,并设置元素的排序方式
        PriorityQueue<ListNode> heap = new PriorityQueue<>((a,b)-> a.val-b.val);
        //遍历链表数组,然后将每个链表的每个节点都放入堆中
        for(int i=0;i<lists.length;i++) {
            while(lists[i] != null) {
                heap.add(lists[i]);
                lists[i] = lists[i].next;
            }
        }
        //初始化一个节点这个值可以是任意数
        ListNode head = new ListNode(-1);
        //通过一个链表指向原链表地址,赋值完成时,打印原链表的指针地址。获取所有值。 这个是解释 为什么操作的是 head 返回的是 res 
        ListNode res = head;
        //从堆中不断取出元素,并将取出的元素串联起来
        while( !heap.isEmpty() ) {
            head.next = heap.poll();
            head = head.next;
        }
        head.next = null;
        return res.next;
    }

在这里插入图片描述

在这里插入图片描述

HashMap

两数之和

class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer,Integer>  map = new HashMap<Integer,Integer>();
        for (int i=0;i<nums.length;i++){
            if(map.containsKey(target- nums[i])){
                return new int[] {map.get(target- nums[i]),i};
            }
            map.put(nums[i],i);
        }
        return new int[0];
    }
}

和为 K 的子数组

class Solution {
    public int subarraySum(int[] nums, int k) {
      Map<Integer,Integer>  map  = new HashMap<>();
      map.put(0,1);
      int sum = 0 ,res =0;
      for (int nu :nums ){
          sum += nu;
          if(map.containsKey(sum - k)){
             res += map.get(sum - k);
          }
          map.put(sum,map.getOrDefault(sum,0)+1);
      }
      return res;
    }
}

无重复字符的最长子串

移动窗口+HashMap

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap<>();
        for (int end = 0, start = 0; end < n; end++) {
            char alpha = s.charAt(end);
            if (map.containsKey(alpha)) {
                start = Math.max(map.get(alpha), start);
            }
            ans = Math.max(ans, end - start + 1);
            map.put(s.charAt(end), end + 1);
        }
        return ans;
    }
}

在这里插入图片描述## search + DP


总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值