leetcoed刷题笔记

数组类算法
给你一个由 不同 整数组成的整数数组 arr 和一个整数 k 。

每回合游戏都在数组的前两个元素(即 arr[0] 和 arr[1] )之间进行。比较 arr[0] 与 arr[1] 的大小,较大的整数将会取得这一回合的胜利并保留在位置 0 ,较小的整数移至数组的末尾。当一个整数赢得 k 个连续回合时,游戏结束,该整数就是比赛的 赢家 。

返回赢得比赛的整数。

题目数据 保证 游戏存在赢家

class Solution {
    public int getWinner(int[] arr, int k) {
        int result = 0;
        int i = 0;
        int count=0;
        while (i<arr.length-1&&count <k){
           if (arr[i]>arr[i+1]){
               arr[i+1]=arr[i];
               i = i+1;
               count=count+1;
           }else{
               i= i+1;
               count=1;
           }
        }
        return arr[i];
    }
}

在代号为 C-137 的地球上,Rick 发现如果他将两个球放在他新发明的篮子里,它们之间会形成特殊形式的磁力。Rick 有 n 个空的篮子,第 i 个篮子的位置在 position[i] ,Morty 想把 m 个球放到这些篮子里,使得任意两球间 最小磁力 最大。

已知两个球如果分别位于 x 和 y ,那么它们之间的磁力为 |x - y| 。

给你一个整数数组 position 和一个整数 m ,请你返回最大化的最小磁力。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/magnetic-force-between-two-balls
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
https://leetcode-cn.com/problems/magnetic-force-between-two-balls/solution/liang-qiu-zhi-jian-de-ci-li-by-leetcode-solution/


class Solution {
    public int maxDistance(int[] position, int m) {
        Arrays.sort(position);
        int left =1,right = position[position.length-1]-position[0], ans=0;
        while (left<=right){
           int mid = (left+right)/2;
           if (check(mid,position,m)){
               ans=mid;
               left=mid+1;
           }else {
               right=mid-1;
           }
        }
        return ans;
    }

    public boolean check(int x,int [] position,int m){
        int pre =position[0], count = 1;
        for (int i = 1; i <position.length ; i++) {
            if (position[i]-pre>=x){
               pre=position[i];
               count+=1;
            }
        }
        return count>=m;
    }
}

给定一个三角形 triangle ,找出自顶向下的最小路径和。

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/triangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
      int n = triangle.size();
      int[][] dp = new int[n][n];
      dp[0][0]=triangle.get(0).get(0);

        for (int i = 1; i <n ; i++) {
            dp[i][0]=dp[i-1][0]+triangle.get(i).get(0);
            for (int j = 1; j <i ; j++) {
                dp[i][j]= Math.min(dp[i-1][j-1],dp[i-1][j])+triangle.get(i).get(j);
            }
            dp[i][i]=dp[i-1][i-1]+triangle.get(i).get(i);
        }
        int min=dp[n-1][0];
        for (int i = 1; i <n ; i++) {
            min=Math.min(dp[n-1][i],min);
            
        }
        return min;
    }
}


给你一个整数数组 arr ,请你删除一个子数组(可以为空),使得 arr 中剩下的元素是 非递减 的。

一个子数组指的是原数组中连续的一个子序列。

请你返回满足题目要求的最短子数组的长度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-subarray-to-be-removed-to-make-array-sorted
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public int findLengthOfShortestSubarray(int[] arr) {
        int n = arr.length;
        int left = 0;
        while (left + 1 < n && arr[left] <= arr[left+1]) {
            left++;
        }
        // [0...left]有序
        if (left == n - 1) {
            return 0;
        }
        // [right...n-1]有序
        int right = n - 1;
        while (right > 0 && arr[right - 1] <= arr[right]) {
            right--;
        }
        
        // 完全删除一边[left+1, n-1], 或者[0...right - 1]
        int result = Math.min(n - left - 1, right);

        // 左边和右边各保留一部分
        int i = 0, j = right;
        
        while (i <= left && j <= n - 1) {
            if (arr[i] <= arr[j]) {
                // [0...i] 和 [j...n-1] 有序, 删除 [i+1...j-1]
                result = Math.min(result, j - i - 1);
                i++;
            } else {
                // 小的+1
                j++;
            }
        }
        return result;
    }
}

作者:avlgood2018
链接:https://leetcode-cn.com/problems/shortest-subarray-to-be-removed-to-make-array-sorted/solution/java-jian-dan-on-by-avlgood2018/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

双指针算法
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
  public int removeElement(int[] nums, int val) {
    int i = 0;
    for (int j = 0; j < nums.length; j++) {
        if (nums[j] != val) {
            nums[i] = nums[j];
            i++;
        }
    }
    return i;
   }
}

滑动窗口法

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int left = 0;
        int sum = 0;
        int len = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            while (sum >= target) {
                len = Math.min(len, i - left + 1);
                sum -= nums[left];
                left++;
            }

        }
        return len==Integer.MAX_VALUE?0:len;
    }
}

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。A

在这里插入图片描述

class Solution {
    public int[][] generateMatrix(int n) {
        int l = 0, r = n - 1, t = 0, b = n - 1;
        int[][] mat = new int[n][n];
        int num = 1, tar = n * n;
        while(num <= tar){
            for(int i = l; i <= r; i++) mat[t][i] = num++; // left to right.
            t++;
            for(int i = t; i <= b; i++) mat[i][r] = num++; // top to bottom.
            r--;
            for(int i = r; i >= l; i--) mat[b][i] = num++; // right to left.
            b--;
            for(int i = b; i >= t; i--) mat[i][l] = num++; // bottom to top.
            l++;
        }
        return mat;
    }
}

链表

虚拟头结点法
删除链表中等于给定值 val 的所有节点。

示例:

class Solution {
  public ListNode removeElements(ListNode head, int val) {
    ListNode sentinel = new ListNode(0);
    sentinel.next = head;

    ListNode prev = sentinel, curr = head;
    while (curr != null) {
      if (curr.val == val) prev.next = curr.next;
      else prev = curr;
      curr = curr.next;
    }
    return sentinel.next;
  }
}

作者:LeetCode
链接:https://leetcode-cn.com/problems/remove-linked-list-elements/solution/yi-chu-lian-biao-yuan-su-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

设计链表


public class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

class MyLinkedList {
    int size;
    ListNode head;  // sentinel node as pseudo-head
    public MyLinkedList() {
        size = 0;
        head = new ListNode(0);
    }

    /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
    public int get(int index) {
        // if index is invalid
        if (index < 0 || index >= size) return -1;

        ListNode curr = head;
        // index steps needed
        // to move from sentinel node to wanted index
        for(int i = 0; i < index + 1; ++i) curr = curr.next;
        return curr.val;
    }

    /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
    public void addAtHead(int val) {
        addAtIndex(0, val);
    }

    /** Append a node of value val to the last element of the linked list. */
    public void addAtTail(int val) {
        addAtIndex(size, val);
    }

    /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
    public void addAtIndex(int index, int val) {
        // If index is greater than the length,
        // the node will not be inserted.
        if (index > size) return;

        // [so weird] If index is negative,
        // the node will be inserted at the head of the list.
        if (index < 0) index = 0;

        ++size;
        // find predecessor of the node to be added
        ListNode pred = head;
        for(int i = 0; i < index; ++i) pred = pred.next;

        // node to be added
        ListNode toAdd = new ListNode(val);
        // insertion itself
        toAdd.next = pred.next;
        pred.next = toAdd;
    }

    /** Delete the index-th node in the linked list, if the index is valid. */
    public void deleteAtIndex(int index) {
        // if the index is invalid, do nothing
        if (index < 0 || index >= size) return;

        size--;
        // find predecessor of the node to be deleted
        ListNode pred = head;
        for(int i = 0; i < index; ++i) pred = pred.next;

        // delete pred.next
        pred.next = pred.next.next;
    }
}

反转链表


class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null){
            return null;
        }
       ListNode pre = null;
       ListNode temp = head;
       while (!(temp.next==null)){
            pre =temp.next;
            temp.next=temp.next.next;
            pre.next=head;
            head=pre;
       }
       return head;

    }
}

寻找环状链表和入口
快慢指针法
思路
https://mp.weixin.qq.com/s/_QVP3IkRZWx9zIpQRgajzA

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

进阶:

你是否可以使用 O(1) 空间解决此题?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

public class Solution {
    public ListNode detectCycle(ListNode head) {
        if (head == null || head.next == null) {
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next!=null&&fast.next.next!=null){
            fast= fast.next.next;
            slow=slow.next;

            if (slow==fast){
                ListNode i = head;

                while (i!=slow){
                    i=i.next;
                    slow=slow.next;
                }
                return i;
            }
        }
        return null;

    }
}

哈希表算法
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

示例 1:

输入: s = “anagram”, t = “nagaram”
输出: true

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-anagram
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public boolean isAnagram(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        int[] table = new int[26];
        for (int i = 0; i < s.length(); i++) {
            table[s.charAt(i) - 'a']++;
        }
        for (int i = 0; i < t.length(); i++) {
            table[t.charAt(i) - 'a']--;
            if (table[t.charAt(i) - 'a'] < 0) {
                return false;
            }
        }
        return true;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/valid-anagram/solution/you-xiao-de-zi-mu-yi-wei-ci-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 true ;不是,则返回 false 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/happy-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


class Solution {
    public boolean isHappy(int n) {
        Set<Integer> set = new HashSet<>();
        while (count(n) !=1){
            if (set.contains(n)){
                return false;
            }
            set.add(n);
            n= count(n);
        }
        return true;
    }
    public int count(int n){
      int sum = 0;
      while (n>0){
          int d =n%10;
          n=n/10;
          sum +=d*d;
      }
      return sum;
    }
}

四数相加
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。

为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间,最终结果不会超过 231 - 1 。

例如:

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4sum-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
        Map<Integer,Integer> map = new HashMap<>();
        int n = A.length;
        for (int i = 0; i <n ; i++) {
            for (int j = 0; j <n ; j++) {
                int sum = A[i]+B[j];
                if (map.containsKey(sum)){
                    map.put(sum,map.get(sum)+1);
                }else {
                    map.put(sum,1);
                }
            }
        }
         int count = 0;
        for (int i = 0; i <n ; i++) {
            for (int j = 0; j <n ; j++) {
                int sum =-C[i]-D[j];
                if (map.containsKey(sum)){
                    count +=map.get(sum);
                }
            }
        }
        return count;
    }
}

双指针加循环
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
     public List<List<Integer>> threeSum(int[] nums) {
       int n = nums.length;
       Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<List<Integer>>();
        for (int first = 0; first <n ; first++) {
            if (first>0&&nums[first]==nums[first-1]){
                continue;
            }
            int thrid = n-1;
            int target= - nums[first];
            for(int second = first +1;second<n;second++){
                if(second>first+1&&nums[second]==nums[second-1]){
                    continue;
                }
                while(second<thrid&&nums[second]+nums[thrid]>target){
                    thrid--;
                }
                if(second==thrid){
                    break;
                }
                if(nums[second]+nums[thrid]==target){
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[first]);
                    list.add(nums[second]);
                    list.add(nums[thrid]);
                    ans.add(list);
                }
            }
            
        }
        return ans;
    }
}

四数之和

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        List<List<Integer>> quadruplets = new ArrayList<List<Integer>>();
        if (nums == null || nums.length < 4) {
            return quadruplets;
        }
        Arrays.sort(nums);
        int length = nums.length;
        for (int i = 0; i < length - 3; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            if (nums[i] + nums[i + 1] + nums[i + 2] + nums[i + 3] > target) {
                break;
            }
            if (nums[i] + nums[length - 3] + nums[length - 2] + nums[length - 1] < target) {
                continue;
            }
            for (int j = i + 1; j < length - 2; j++) {
                if (j > i + 1 && nums[j] == nums[j - 1]) {
                    continue;
                }
                if (nums[i] + nums[j] + nums[j + 1] + nums[j + 2] > target) {
                    break;
                }
                if (nums[i] + nums[j] + nums[length - 2] + nums[length - 1] < target) {
                    continue;
                }
                int left = j + 1, right = length - 1;
                while (left < right) {
                    int sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if (sum == target) {
                        quadruplets.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        while (left < right && nums[left] == nums[left + 1]) {
                            left++;
                        }
                        left++;
                        while (left < right && nums[right] == nums[right - 1]) {
                            right--;
                        }
                        right--;
                    } else if (sum < target) {
                        left++;
                    } else {
                        right--;
                    }
                }
            }
        }
        return quadruplets;
    }
}

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/4sum/solution/si-shu-zhi-he-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

kmp算法
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

package 算法.KMPAlgorithm;

import java.util.Arrays;

public class Kmp {
    public static void main(String[] args) {
        String str1 = "BBC ABCDAB ABCDABCDABDE";
        String str2 ="ABCDABD";//结果15
        int[] next=kmpNext(str2);
        //输出部分匹配值表
        System.out.println("next:"+ Arrays.toString(next));
        //匹配字符串,返回索引值
        System.out.println(kmpSearch(str1,str2,next));

    }

    //获取字串的字符匹配值表
    public static int[] kmpNext(String str){
        //创建一个next表,每个下标存储的值是部分匹配值,也可以理解为前缀与后缀最大相同的·1个数
        int [] next = new int[str.length()];
         //第一个字符的匹配值一定为0
        next[0]=0;
        for (int i = 1,j=0; i <str.length() ; i++) {
            //如果str.charAt(i)!=str.charAt(j)
            while(j>0&&str.charAt(i)!=str.charAt(j)){
                j=next[j-1];
            }

            //当满足str.charAt(i)==str.charAt(j),部分匹配值加一
            if(str.charAt(i)==str.charAt(j)){
                j++;
            }
            next[i]=j;
        }
        return next;
    }
    //得到字串的字符串匹配表后,我们可以开始写kmp算法了
    //参数 第一个是源字符串,第二个是要匹配的字符串 数组是字串2的部分匹配值表
    //如果匹配返回第一个匹配值的索引,如果不匹配,返回-1
    public static int kmpSearch(String str1,String str2,int[] next){
        for (int i = 0,j=0; i <str1.length() ; i++) {

            while (j>0&&str1.charAt(i)!=str2.charAt(j)){
                j=next[j-1];
            }

            if(str1.charAt(i)==str2.charAt(j)){
                j++;
            }
            if (j==str2.length()){
                return i-j+1;
            }

        }
        return -1;
    }
}

字符串反转
双指针

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public void reverseString(char[] s) {
         int left = 0;
         int right= s.length-1;
         while(left<right){
             char temp =s[left];
             s[left]=s[right];
             s[right]=temp;
             left++;
             right--;
         }
    }
}

字符串反转二
给定一个字符串 s 和一个整数 k,你需要对从字符串开头算起的每隔 2k 个字符的前 k 个字符进行反转。

如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-string-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public String reverseStr(String s, int k) {
        char[] a = s.toCharArray();
        for (int start = 0; start < a.length; start += 2 * k) {
            int i = start, j = Math.min(start + k - 1, a.length - 1);
            while (i < j) {
                char tmp = a[i];
                a[i++] = a[j];
                a[j--] = tmp;
            }
        }
        return new String(a);
    }
}

替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

//replace(int start, int end, String str):将起始位置为start,结束位置为end-1的子串替换为str。不生成新的StringBuilder对象,在原来的StringBuilder对象上修改。

class Solution {
    public String replaceSpace(String s) {
        StringBuffer str = new StringBuffer(s);
         int index = str.indexOf(" ");
        while(index != -1){
            str.replace(index,index+1,"%20");
            index = str.indexOf(" ",index);//查找指定字符或字符串在字符串中第一次出现地方的索引,未找到的情况返回 -1.
           // 从index的地方开始找,返回第一次出现的索引
        }
        String result = str.toString();
        return result;
    }
}

反转单词

给定一个字符串,逐个翻转字符串中的每个单词。

说明:

无空格字符构成一个 单词 。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public String reverseWords(String s) {
        String str = s.trim();
        String[] strings = str.split("\\s+");
        int n = strings.length;
        int left = 0;
        int right = n - 1;
        while (left < right) {
            String temp = strings[left];
            strings[left] = strings[right];
            strings[right] = temp;
            left++;
            right--;
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i <n ; i++) {
            stringBuilder.append(i==n-1?strings[i]:strings[i]+" ");
        }
        return new String(stringBuilder);

    }
}
class Solution {
    public String reverseWords(String s) {
        // 除去开头和末尾的空白字符
        s = s.trim();
        // 正则匹配连续的空白字符作为分隔符分割
        List<String> wordList = Arrays.asList(s.split("\\s+"));
        Collections.reverse(wordList);
        return String.join(" ", wordList);
    }
}



给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {

    public boolean isValid(String s) {

        int n = s.length();
        Stack<Character> stack = new Stack<>();
        
        if (n % 2 != 0) {

            return false;
        }
        char[] c = s.toCharArray();
        for (int i=0;i<n;i++) {

            if (c[i] == '(') {

                stack.push(')');
            } else if (c[i] == '[') {

                stack.push(']');
            } else if (c[i] == '{'){

                stack.push('}');
            } else if (stack.isEmpty() || c[i] != stack.pop()) {

                return false;
            }
        }
        //当全部匹配结束后,栈中仍有元素则返回false
        if (!stack.isEmpty()) {

            return false;
        }
        return true;
    }
}

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。
给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/evaluate-reverse-polish-notation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    public int evalRPN(String[] tokens) {
    Stack<Integer> stack = new Stack<>();
    for(int i = 0; i < tokens.length; i++) {
        String cur = tokens[i];
        if ("+".equals(cur)) {
            stack.push(stack.pop() + stack.pop());
        }else if ("-".equals(cur)) {
            Integer num1 = stack.pop();
            Integer num2 = stack.pop();
            stack.push(num2 - num1);
        }else if ("*".equals(cur)) {
            stack.push(stack.pop() * stack.pop());
        }else if ("/".equals(cur)) {
            Integer num1 = stack.pop();
            Integer num2 = stack.pop();
            stack.push(num2 / num1);
        }else {
            stack.push(Integer.valueOf(cur));
        }
    }
    return stack.pop();
    }
}

1、编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

示例 1:

输入: [“flower”,“flow”,“flight”]
输出: “fl”

示例 2:

输入: [“dog”,“racecar”,“car”]
输出: “”
解释: 输入不存在公共前缀。

思路:
当字符串数组长度为 0 时则公共前缀为空,直接返回
令最长公共前缀 ans 的值为第一个字符串,进行初始化
遍历后面的字符串,依次将其与 ans 进行比较,两两找出公共前缀,最终结果即为最长公共前缀
如果查找过程中出现了 ans 为空的情况,则公共前缀不存在直接返回
时间复杂度:O(s)O(s)O(s),s 为所有字符串的长度之和

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length == 0) 
            return "";
        String ans = strs[0];
        for(int i =1;i<strs.length;i++) {
            int j=0;
            for(;j<ans.length() && j < strs[i].length();j++) {
                if(ans.charAt(j) != strs[i].charAt(j))
                    break;
            }
            ans = ans.substring(0, j);
            if(ans.equals(""))
                return ans;
        }
        return ans;
    }
}


开启两个线程A、B,打印1到10,线程A打印奇数(1、3、5、7、9),线程B打印偶数(2、4、6、8、10)。


class TaskEvenOdd implements Runnable {
    private int max;
    private Printer print;
    private boolean isEvenNumber;

    public TaskEvenOdd(Printer print, int max, boolean isEvenNumber) {
        this.max = max;
        this.print = print;
        this.isEvenNumber = isEvenNumber;
    }

    // standard constructors

    @Override
    public void run() {
        int number = isEvenNumber ? 2 : 1;
        while (number <= max) {
            if (isEvenNumber) {
                print.printEven(number);
            } else {
                print.printOdd(number);
            }
            number += 2;
        }
    }

    static class Printer {
        private volatile boolean isOdd=true;

        synchronized void printEven(int number) {
            while (isOdd) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println(Thread.currentThread().getName() + ":" + number);
            isOdd = true;
            notify();
        }

        synchronized void printOdd(int number) {
            while (!isOdd) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println(Thread.currentThread().getName() + ":" + number);
            isOdd = false;
            notify();
        }
    }

    public static void main(String... args) {
        Printer print = new Printer();
        Thread t1 = new Thread(new TaskEvenOdd(print, 10, true),"Odd");
        Thread t2 = new Thread(new TaskEvenOdd(print, 10, false),"Even");
        t1.start();
        t2.start();
    }
}

写一个Map转换成JavaBean的工具类方法,实现如下mapToObject方法(使用Java反射,不允许使用第三方类库)

public static T mapToObject(Map<String, Object> map, Class beanClass){

}

    public static Object mapToObject(Map<String, Object> map, Class<?> beanClass){      
        if (map == null)    
            return null;      
        Object obj = null;  
        try {  
            obj = beanClass.newInstance();    
            Field[] fields = obj.getClass().getDeclaredFields();                       for (Field field : fields) {      
                int mod = field.getModifiers();      
                if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){      
                    continue;      
                }      
                field.setAccessible(true);      
                field.set(obj, map.get(field.getName()));     
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }     
        return obj;      
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值