zoukankan      html  css  js  c++  java
  • leetcode -1

    001 两数之和:map,一次遍历

    class Solution {
        public int[] twoSum(int[] nums, int target) {
            Map<Integer, Integer> map = new HashMap<>();
            for (int i = 0; i < nums.length; i++) {
                int complement = target - nums[i];
                if (map.containsKey(complement)) {
                    return new int[] { map.get(complement), i };
                }
                map.put(nums[i], i);
            }
            throw new IllegalArgumentException("No two sum solution");
        }
    }
    

    146 LRU缓存机制:LinkedHashMap 覆写removeEldestEntry;HashMap + 链表

    //方法1:LinkedHashMap
    class LRUCache extends LinkedHashMap<Integer, Integer>{
        private int capacity;
        
        public LRUCache(int capacity) {
            super(capacity, 0.75F, true);
            this.capacity = capacity;
        }
    
        public int get(int key) {
            return super.getOrDefault(key, -1);
        }
    
        public void put(int key, int value) {
            super.put(key, value);
        }
    
        @Override
        protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
            return size() > capacity; 
        }
    }
    
    //方法2:
    public class LRUCache {
        class DLinkedNode {
            int key;
            int value;
            DLinkedNode prev;
            DLinkedNode next;
            public DLinkedNode() {}
            public DLinkedNode(int _key, int _value) {key = _key; value = _value;}
        }
    
        private Map<Integer, DLinkedNode> cache = new HashMap<Integer, DLinkedNode>();
        private int size;
        private int capacity;
        private DLinkedNode head, tail;
    
        public LRUCache(int capacity) {
            this.size = 0;
            this.capacity = capacity;
            // 使用伪头部和伪尾部节点
            head = new DLinkedNode();
            tail = new DLinkedNode();
            head.next = tail;
            tail.prev = head;
        }
    
        public int get(int key) {
            DLinkedNode node = cache.get(key);
            if (node == null) {
                return -1;
            }
            // 如果 key 存在,先通过哈希表定位,再移到头部
            moveToHead(node);
            return node.value;
        }
    
        public void put(int key, int value) {
            DLinkedNode node = cache.get(key);
            if (node == null) {
                // 如果 key 不存在,创建一个新的节点
                DLinkedNode newNode = new DLinkedNode(key, value);
                // 添加进哈希表
                cache.put(key, newNode);
                // 添加至双向链表的头部
                addToHead(newNode);
                ++size;
                if (size > capacity) {
                    // 如果超出容量,删除双向链表的尾部节点
                    DLinkedNode tail = removeTail();
                    // 删除哈希表中对应的项
                    cache.remove(tail.key);
                    --size;
                }
            }
            else {
                // 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
                node.value = value;
                moveToHead(node);
            }
        }
    
        private void addToHead(DLinkedNode node) {
            node.prev = head;
            node.next = head.next;
            head.next.prev = node;
            head.next = node;
        }
    
        private void removeNode(DLinkedNode node) {
            node.prev.next = node.next;
            node.next.prev = node.prev;
        }
    
        private void moveToHead(DLinkedNode node) {
            removeNode(node);
            addToHead(node);
        }
    
        private DLinkedNode removeTail() {
            DLinkedNode res = tail.prev;
            removeNode(res);
            return res;
        }
    }


    004 寻找两个正序数组的中位数:Arrays.sort();…… ;
    005 最长回文子串:中心扩散法,注意s.substring(left, right)表示包含left不包含right的子串

    class Solution {
     public String longestPalindrome(String s) {
    
            int  len = s.length();
            String ans = "";
    
            for (int i = 0; i < len; i++) {
                String odd = maxLengthPalidrome(s, i, i);
                String edd = maxLengthPalidrome(s, i, i + 1);
    
                String tmp = odd.length() > edd.length() ? odd : edd;
                ans = ans.length() > tmp.length() ? ans : tmp;
            }
            return ans;
        }
    
        private String maxLengthPalidrome(String s, int i, int j) {
            int left = i;
            int right = j;
            while (left >= 0 && right < s.length()) {
                if(s.charAt(left) == s.charAt(right)){
                    left--;
                    right++;
                }else {
                    break;
                }
            }
            return s.substring(left+1, right);
    
        }
    
    }


    206 翻转链表:声明 pre=null, current= head, while(curr!=null){ tmp = curr.next; curr.next = pre; pre = current; current = tmp;} return prev;

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode reverseList(ListNode head) {
            
            if(head == null) {
                return head;
            }
    
            ListNode curr = head;
            ListNode prev = null;
            while (curr != null) {
                ListNode tmp = curr.next;
                curr.next = prev;
                prev = curr;
                curr = tmp;
            }
            
            return prev;
        }
    }


    021 合并两个有序链表:循环迭代,声明 head = new ListNode(0); curr = head,循环curr,避免无法返回的问题,因为需要返回头指针,即 head.next

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
            ListNode head = new ListNode(0);
            ListNode curr = head;
            while (l1 != null && l2 != null){
                if (l1.val < l2.val) {
                    curr.next = l1;
                    l1 = l1.next;
                } else {
                    curr.next = l2;
                    l2 = l2.next;
                }
                curr = curr.next;
            }
    
            curr.next = l1 == null? l2 : l1;
            return head.next;
        }
    
    }


    015 三数之和:先排序,双指针+循环,注意结果去重(3个地方),防止越界,Arrays.asList(^)

    class Solution {
        public List<List<Integer>> threeSum(int[] nums) {
            int length = nums.length;
            Arrays.sort(nums);
            List<List<Integer>> ans = new ArrayList<List<Integer>>();
    
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] > 0) {
                    continue;
                }
                if (i >= 1 && nums[i] == nums[ i- 1]) {
                    continue;
                }
                int left = i +1;
                int right = length -1;
                while (left < right) {
                    int sum = nums[i] + nums[left] + nums[right];
                    if (sum == 0) {
    
                        ans.add(Arrays.asList(nums[i], nums[left],nums[right]));
                        
                        while (left < right && nums[left] == nums[left + 1]){
                            left++;
                        }
                        while (left < right && nums[right] == nums[right - 1]){
                            right--;
                        }
                        left++;
                        right--;
                    } else if (sum > 0) {
                        right--;
                    } else {
                        left++;
                    }
                }
            }
            return ans;
    
        }
    }
    

     

    046 全排列:回溯法

    public static List<List<Integer>> permute(int[] nums) {

    List<List<Integer>> res = new ArrayList<List<Integer>>();
    int[] visited = new int[nums.length];
    backtrack(res, nums, new ArrayList<Integer>(), visited);
    return res;

    }

    private static void backtrack(List<List<Integer>> res, int[] nums, ArrayList<Integer> tmp, int[] visited) {
    //tmp 用来临时保存一次全排列的结果
    if (tmp.size() == nums.length) {
    res.add(new ArrayList<Integer>(tmp));
    return;
    }
    for (int i = 0; i < nums.length; i++) {
    if (visited[i] == 1) {
    continue;
    }
    visited[i] = 1;
    tmp.add(nums[i]);
    backtrack(res, nums, tmp, visited);
    //回溯结束之后,更新tmp,还原
    visited[i] = 0;
    tmp.remove(tmp.size() - 1);
    }
    }

    384 打乱数组:

    public int[] reset() {
      array = original;
      //记得再复制一份original
      original = original.clone();
      return original;
    }
    public int[] shuffle() {
      // i只能与后面未交换的位置进行交换
      for (int i = 0; i < array.length; i++) {
        swapAt(i, rand.nextInt(array.length - i) + i);
      }
      return array;
    }

    053 最大子序列和:

    public static int maxSubArray(int[] nums) {
        int sum = 0;
        int ans = nums[0];
        for (int num : nums) {
            if (sum > 0) {
                sum += num;
            } else {
                sum = num;
            }
            ans = Math.max(sum, ans);
        }
        return ans;
    }                    

    253 会议室II,VIP
    289 生命游戏:特殊值,使用-1和2代表生命状态的转化;遍历的边界问题,使用数组{-1,0,1}来简化代码

    class Solution {
    static int[] location = new int[]{-1,0,1};
    
        public static void gameOfLife(int[][] board) {
            if (board == null ){
                return ;
            }
            int row = board.length;
            int col = board[0].length;
    
            for (int i = 0; i < row;i++) {
                for (int j = 0; j < col; j++) {
                    int sum = statistic(board, i, j, row, col);
                    //统计活的个数
                    if (board[i][j] == 0 && sum == 3){
                        board[i][j] = 2;
                    } else if (board[i][j] == 1 && sum < 2){
                        board[i][j] = -1;
                    } else if (board[i][j] == 1 && sum > 3){
                        board[i][j] = -1;
                    }
                }
            }
    
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    if (board[i][j] == 2){
                        board[i][j] = 1;
                    }else if (board[i][j] == -1){
                        board[i][j] = 0;
                    }
                }
            }
        }
    
        private static int statistic(int[][] board, int row, int col, int maxRow, int maxCol) {
            int total = 0;
            for (int i = 0; i< location.length; i++) {
                for (int j = 0; j < location.length; j++) {
                    if (!(location[i] == 0 && location[j] == 0)) {
                        // 相邻位置的坐标,注意是 location【i】而不是i
                        int r = (row + location[i]);
                        int c = (col + location[j]);
    
                        // 查看相邻的细胞是否是活细胞
                        if ((r < maxRow && r >= 0) && (c < maxCol && c >= 0) ) {
                            if((Math.abs(board[r][c]) == 1)){
                            total++;
                            }
                        }
                    }
                    }
                }
            return total;
        }
    }
    

      

    128 最长连续序列:set+Math.max: 输入:[100,4,200,1,3,2],输出: 4,最长连续序列是[1,2,3,4]。它的长度为4。

    class Solution {
     public static int longestConsecutive(int[] nums) {
    
            if(nums == null || nums.length == 0){
                return 0;
            }
            Set<Integer> set = new HashSet<Integer>();
    
            for(int i = 0; i< nums.length; i++) {
                set.add(nums[i]);
            }
    
            int ans = 0;
            for (int i = 0; i< nums.length; i++) {
                if (set.contains(nums[i] - 1)){
                    continue;
                }
                int tmp = nums[i];
                int tmpLength = 0;
                while (set.contains(tmp)){
                    tmpLength += 1;
                    tmp += 1;
                    ans = Math.max(tmpLength, ans);
                }
            }
            return ans;
        }
    }

    148 排序链表:归并排序+递归:

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
     public ListNode sortList(ListNode head) {
    
            if(head == null || head.next == null){
                return head;
            }
            
            ListNode  fast = head.next;
            ListNode slow = head;
            while(fast != null && fast.next != null){
                fast = fast.next.next;
                slow = slow.next;
            }
            
            ListNode tmp = slow.next;
            slow.next = null;
            
            ListNode left = sortList(head);
            ListNode right = sortList(tmp);
    
            ListNode h = new ListNode(0);
            ListNode res = h;
            
            while(left!= null && right != null){
                if (left.val < right.val){
                    h.next = left;
                    left = left.next;
                }else {
                    h.next = right;
                    right = right.next;
                }
                h = h.next;
            }
    
            h.next = left == null? right : left;
            return res.next;
        }
    }
    

      

    300 最长上升子序列:动态规划

    class Solution {
    public static int lengthOfLIS(int[] nums) {
    
            if (nums== null || nums.length == 0){
                return 0;
            }
    
            int[] dp = new int[nums.length];
            dp[0] = 1;
            for (int i  = 0; i < nums.length; i++){
                int maxVal = 0;
                for (int j = 0;j < i; j++){
                    if (nums[j] < nums[i]){
                        maxVal = Math.max(maxVal, dp[j]);
                    }
                }
                dp[i] = maxVal + 1;
            }
            
            int res = 0;
            for (int i  = 0; i < nums.length; i++){
                res = Math.max(res, dp[i]);
            }
            return res;
        }
    }


    179 最大数:注意:Comparator,排序之后。0是asStrs的最大值,则返回0,避免多个0

    思考:大数据全排列

    class Solution {
        private class LargerNumberComparator implements Comparator<String> {
            @Override
            public int compare(String a, String b) {
                String order1 = a + b;
                String order2 = b + a;
               return order2.compareTo(order1);
            }
        }
    
        public String largestNumber(int[] nums) {
            String[] asStrs = new String[nums.length];
            for (int i = 0; i < nums.length; i++) {
                asStrs[i] = String.valueOf(nums[i]);
            }
            Arrays.sort(asStrs, new LargerNumberComparator());
            String largestNumberStr = new String();
            for (String numAsStr : asStrs) {
                largestNumberStr += numAsStr;
            }
            return largestNumberStr;
        }
    }
    

     

    022 括号生成:回溯法

    class Solution {
        public List<String> generateParenthesis(int n) {
            List<String> res = new ArrayList<>();
            dfs(res, n, n, "");
            return res;
        }

        private void dfs(List<String> res, int left, int right, String curStr) {
            if (left == 0 && right == 0) { // 左右括号都不剩余了,说明找到了有效的括号
                res.add(curStr);
                return;
            }
            //左括号只有剩余的时候才可以选,如果左括号的数量已经选完了,是不能再选左括号了。
            //如果选完了左括号我们是还可以选择右括号的。
            if (left < 0)
                return;
            // 如果右括号剩余数量小于左括号剩余的数量,说明之前选择的无效
            if (right < left)
                return;
                //选择左括号
                dfs(res, left - 1, right, curStr + "(");
                //选择右括号
                dfs(res, left, right - 1, curStr + ")");
        }
    }

    200 岛屿数量:BFS,

    class Solution {
        public int numIslands(char[][] grid) {
            if (grid == null || grid.length == 0){
                return 0;
            }
            int ans = 0;
            int row = grid.length;
            int col = grid[0].length;
            for (int i = 0; i< row; i++) {
                for (int j = 0; j< col; j++){
                    if (grid[i][j] == '1'){
                        dfs(grid, i, j);
                        ans++;
                    }
                }
            }
            return ans;
        }
    
        private void dfs(char[][] grid, int i, int j) {
            int row = grid.length;
            int col = grid[0].length;
            if (i < 0 || j < 0 || i >= row || j >= col){
                return;
            }
            if (grid[i][j] == '0'){
                return;
            }
            grid[i][j]='0';
            dfs(grid, i-1, j);
            dfs(grid, i , j-1);
            dfs(grid, i+1, j);
            dfs(grid, i, j+1);
        }
    }
    

      

    287 寻找重复数:二分查找

    class Solution {
        public int findDuplicate(int[] nums) {
            int n = nums.length;
            int l = 1, r = n - 1, ans = -1;
            while (l <= r) {
                int mid = (r-l) / 2 + l;
                int cnt = 0;
                for (int i = 0; i < n; ++i) {
                    if (nums[i] <= mid) {
                        cnt++;
                    }
                }
                if (cnt <= mid) {
                    l = mid + 1;
                } else {
                    r = mid - 1;
                    ans = mid;
                }
            }
            return ans;
        }
    }

    054 螺旋矩阵

    class Solution {
        public List<Integer> spiralOrder(int[][] matrix) {
            List<Integer> list = new ArrayList<Integer>();
            if (matrix == null || matrix.length == 0) {
                return list;
            }
            int m = matrix.length;
            int n = matrix[0].length;
            int i = 0;
    
            //统计矩阵从外向内的层数,如果矩阵非空,那么它的层数至少为1层
            int count = (Math.min(m, n) + 1) / 2;
            //从外部向内部遍历,逐层打印数据
            while (i < count) {
                for (int j = i; j < n - i; j++) {
                    list.add(matrix[i][j]);
                }
                for (int j = i + 1; j < m - i; j++) {
                    list.add(matrix[j][(n - 1) - i]);
                }
    
                for (int j = (n - 1) - (i + 1); j >= i && (m - 1 - i != i); j--) {
                    list.add(matrix[(m - 1) - i][j]);
                }
                for (int j = (m - 1) - (i + 1); j >= i + 1 && (n - 1 - i) != i; j--) {
                    list.add(matrix[j][i]);
                }
                i++;
            }
            return list;
        }
    }
    

     

  • 相关阅读:
    MySQL 简单查询(实验回顾)
    PicGo + Gitee 创建图床,Typora竟还有这种功能
    SQL 条件判断
    django ORM中的复选MultiSelectField的使用
    with的用法
    django update-or-create的用法
    获取异常文件
    支付宝支付
    单例模式创建
    数据类模型
  • 原文地址:https://www.cnblogs.com/jjfan0327/p/13554636.html
Copyright © 2011-2022 走看看