文章目录

  • 1.找到字符串的最长无重复字符子串长度?
  • 2.大数加法?
  • 3.字符串排序?(快排)
  • 4.合并两个有序链表?
  • 5 两个链表的第一个公共节点?(hashMap思想)
  • 6.数组中的最长连续子序列?
  • 7.矩阵的最小路径和?
  • 8.矩阵(有序)查找?
  • 9.数字在升序数组中出现的次数?
  • 10.二叉树的层序遍历(即每层的数据)?
  • 11.反转单链表
  • 12.最小的K个数?(选择排序思路)
  • 13.包含重复数字的二分查找?
  • 14.寻找第K大的数?(快排思想)
  • 15给出一个整数数组,请在数组中找出两个加起来等于目标值的数?
  • 16.求平方根?
  • 17. 一个升序链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素
  • 18.二叉树的最大路径和(节点可为负)?
  • 19.判断二叉树是否对称?
  • 20.找出所有根节点到叶子节点路径和为sum的路径?
  • 21. 二叉树中是否存在节点和为指定值的路径?
  • 22.集合的所有子集?
  • 23. 查找字符串数组中的最长公共前缀?
  • 24. 旋转有序数组的二分查找?
  • 25、有一个数组,其中第 i 个元素是股票在第i 天的价格,计算可以获得的最大收益
  • 26、求链表环的入口(包含多个环的情况)?
  • 27、二分查找
  • 28、快速排序
  • 29、合并有序数组?
  • 30、求二进制数中1的个数?
  • 31、最大公约数和最小公倍数?
  • 32、判断链表是否相交?


1.找到字符串的最长无重复字符子串长度?

public static int lengthOfLongestSubstring(String s) {
        int n = s.length(), ans = 0;
        Map<Character, Integer> map = new HashMap(); // current index of character
        // try to extend the range [i, j]
        for (int j = 0, i = 0; j < n; j++) {
            if (map.containsKey(s.charAt(j))) {
                i = Math.max(map.get(s.charAt(j)), i);
            }
            ans = Math.max(ans, j - i + 1);
            map.put(s.charAt(j), j + 1);
        }
        return ans;
    }

2.大数加法?

public static String solve(String str1, String str2) {
    int[] num1 = new int[str1.length()];
    int[] num2 = new int[str2.length()];
    int len = 1 + Math.max(str1.length(), str2.length());
    int[] sum = new int[len];
    for (int a = 0; a < str1.length(); a++) {
      // 将str1数字逐个倒序放入数组num1[]
      num1[str1.length() - a - 1] = Integer.parseInt(str1.substring(a, a + 1));
    }
    for (int b = 0; b < str2.length(); b++) {
      // 将str2数字逐个倒序放入数组num2[]
      num2[str2.length() - b - 1] = Integer.parseInt(str2.substring(b, b + 1));
    }
    int overflow = 0;
    for (int i = 0; i < len - 1; i++) {
      // 逐位相加,满10进1
      sum[i] = num2[i] + num1[i] + overflow;
      if (sum[i] >= 10) {
        sum[i] = sum[i] % 10;
        overflow = 1;
      } else {
        overflow = 0;
      }
    }
    sum[len - 1] = overflow;
    StringBuffer sb = new StringBuffer();
    for (int j = len - 1; j >= 0; j--) {
      sb.append(sum[j]);
    }
    return sb.toString();
  }

3.字符串排序?(快排)

static void quickSort(String[] arr, int left, int right){ // 快速排序算法
    String f, t;
    int rtemp, ltemp;
    ltemp = left;
    rtemp = right;
    f = arr[(left + right) / 2]; // 分界值
    while (ltemp < rtemp) {
      while (arr[ltemp].compareTo(f) < 0) {
        ++ltemp;
      }
      while (arr[rtemp].compareTo(f) > 0) {
        --rtemp;
      }
      if (ltemp <= rtemp) {
        t = arr[ltemp];
        arr[ltemp] = arr[rtemp];
        arr[rtemp] = t;
        --rtemp;
        ++ltemp;
      }
    }
    if (ltemp == rtemp) {
      ltemp++;
    }
    if (left < rtemp) {
      quickSort(arr, left, ltemp - 1); // 递归调用
    }
    if (ltemp < right) {
      quickSort(arr, rtemp + 1, right); // 递归调用
    }
  }

4.合并两个有序链表?

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode prehead = new ListNode(-1);	//定义一个结点值为-1新结点对象
        ListNode prev = prehead;			//定义头指针
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {			
                prev.next = l1;				//新结点的下一个指针指向l1
                l1 = l1.next;				//l1后移
            } else {
                prev.next = l2;				//新结点的下一个指针指向l2
                l2 = l2.next;				//l2后移
            }
            prev = prev.next;				//指针后移
        }
        // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
        prev.next = l1 == null ? l2 : l1;	
        return prehead.next;				
    }

5 两个链表的第一个公共节点?(hashMap思想)

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
    ListNode current1 = pHead1;
    ListNode current2 = pHead2;
    HashMap<ListNode, Integer> hashMap = new HashMap<ListNode, Integer>();
    while (current1 != null) {
      hashMap.put(current1, null);
      current1 = current1.next;
    }
    while (current2 != null) {
      if (hashMap.containsKey(current2))
        return current2;
      current2 = current2.next;
    }
    return null;
  }

6.数组中的最长连续子序列?

public static int MLS(int[] arr) {
    if (arr == null || arr.length == 0) {
      return 0;
    }
    int res = 1, sum = 1;
    Arrays.sort(arr);
    for (int i = 0; i < arr.length - 1; i++) {
      if (arr[i + 1] == arr[i]) {
        continue;
      } else if (arr[i + 1] == arr[i] + 1) {
        sum++;
        res = Math.max(res, sum);
      } else {
        sum = 1;
      }
    }
    return res;
  }

7.矩阵的最小路径和?

public int minPathSum(int[][] matrix) {
    final int m = matrix.length, n = (m == 0 ? 0 : matrix[0].length);
    if (m == 0 || n == 0)
      return 0;
    int[][] dp = new int[matrix.length][matrix[0].length];
    dp[0][0] = matrix[0][0];
    int up, left;
    for (int i = 0; i < m; ++i) {
      for (int j = 0; j < n; ++j) {
        if (i == 0 && j == 0)
          continue;
        up = Integer.MAX_VALUE;
        left = Integer.MAX_VALUE;
        if (i - 1 >= 0)
          up = dp[i - 1][j];
        if (j - 1 >= 0)
          left = dp[i][j - 1];
        dp[i][j] = matrix[i][j] + Math.min(up, left);
      }
    }
    return dp[m - 1][n - 1];
  }

8.矩阵(有序)查找?

public boolean searchMatrix(int[][] matrix, int target) {
    if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
      return false;
    int row = matrix.length;
    int col = matrix[0].length;
    int start = 0, end = row * col - 1;
    while (start <= end) {
      int mid = (start + end) / 2;
      int value = matrix[mid / col][mid % col];
      if (value > target) {
        end = mid - 1;
      } else if (value < target) {
        start = mid + 1;
      } else {
        return true;// 找到了value==target
      }
    }
    return false;
  }

9.数字在升序数组中出现的次数?

public static int GetNumberOfK(int[] array, int k) {
    if (array == null || array.length == 0)
      return 0;
    int left = 0, right = array.length;
    while (left < right) {
      int mid = (right + left) / 2;
      if (array[mid] < k) {
        left = mid + 1;
      } else {
        right = mid;
      }
    }
    int lres = left;//最左位置
    left = 0;
    right = array.length;
    while (left < right) {
      int mid = (right + left) / 2;
      if (array[mid] <= k) {
        left = mid + 1;
      } else {
        right = mid;
      }
    }
    int rres = left;//最右位置
    return rres - lres;//计算位置差即出现次数
  }

10.二叉树的层序遍历(即每层的数据)?

public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) {
    ArrayList<ArrayList<Integer>> rs = new ArrayList<>();
    if (root == null) {
      return rs;
    }
    ArrayList<TreeNode> list = new ArrayList<>();
    list.add(root);
    while (!list.isEmpty()) {
      int s = list.size();
      ArrayList<Integer> temp = new ArrayList<>();
      for (int i = 0; i < s; i++) {
        TreeNode t = list.get(0);
        temp.add(t.val);
        if (t.left != null) {
          list.add(t.left);
        }
        if (t.right != null) {
          list.add(t.right);
        }
        list.remove(0);
      }
      rs.add(temp);
    }
    return rs;
  }

11.反转单链表

头节点插入:

public static ListNode reverseListByInsert(ListNode listNode){
        //定义一个带头节点的
        ListNode resultList = new ListNode(-1);
        //循环节点
        ListNode p = listNode;
        while(p!= null){
            //保存插入点之后的数据
            ListNode tempList = p.next;
            p.next = resultList.next;
            resultList.next = p;
            p = tempList;
        }
        return resultList.next;
    }

就地反转:

public static ListNode reverseListByLocal(ListNode listNode){
        ListNode resultList = new ListNode(-1);
        resultList.next= listNode;
        ListNode p = listNode;
        ListNode pNext = p.next;
        while (pNext!=null){
            p.next = pNext.next;
            pNext.next = resultList.next;
            resultList.next = pNext;
            pNext=p.next;
        }
        return resultList.next;
    }

12.最小的K个数?(选择排序思路)

public static ArrayList<Integer> GetLeastNumbers_Solution(int[] input, int k) {
    int f = 0;
    ArrayList<Integer> s = new ArrayList<Integer>();
    if (k > input.length)
      return s;
    for (int i = 0; i < k; i++) {
      for (int j = i + 1; j < input.length; j++) {
        if (input[i] > input[j]) {
          f = input[i];
          input[i] = input[j];
          input[j] = f;
        }
      }
      s.add(input[i]);
    }
    return s;
  }

13.包含重复数字的二分查找?

输出在数组中第一个大于等于查找值的位置,如果数组中不存在这样的数,则输出数组长度加一。
输入:5,4,[1,2,4,4,5] 返回: 3

public static int upper_bound_(int n, int v, int[] a) {
    int low = 0;
    int high = n;
    if (a[n - 1] < v)
      return n + 1;
    while (low < high) {
      int mid = (high + low) / 2;
      if (a[mid] < v) {
        low = mid + 1;
      } else {
        high = mid;
      }
    }
    return low + 1;
  }

14.寻找第K大的数?(快排思想)

public int findKth(int[] a, int n, int K) {
    return qs(a, 0, a.length - 1, a.length - K); // 第K大数 的下标
  }

  int qs(int[] a, int left, int right, int k) {
    int p = partition(a, left, right);
    if (p == k) {
      return a[p];
    } else if (p > k) {
      return qs(a, left, p - 1, k);
    } else {
      return qs(a, p + 1, right, k);
    }
  }

  int partition(int a[], int left, int right) {
    int t = a[left];
    while (left < right) {
      while (left < right && a[right] > t) {
        right--;
      }
      a[left] = a[right];
      while (left < right && a[left] < t) {
        left++;
      }
      a[right] = a[left];
    }
    a[left] = t;
    return left;
  }

15给出一个整数数组,请在数组中找出两个加起来等于目标值的数?

public int[] twoSum(int[] numbers, int target) {
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int i = 0; i < numbers.length; i++) {
      if (map.get(target - numbers[i]) != null) {
        return new int[] {map.get(target - numbers[i]) + 1, i + 1};//对应两个数是第几个元素所以+1
      }
      map.put(numbers[i], i);
    }
    return null;
  }

16.求平方根?

public int sqrt (int x) {
    if(x==1||x==0){
        return x;
    }
    long left = 1;
    long right = x;
    while (left <= right) {
        long mid = (right + left) /2;
        if (mid * mid == x)
            return (int) mid;
        if (mid * mid < x)
            left = (int)mid + 1;
        if (mid * mid > x)
            right = (int)mid - 1;
    }
    if (right * right < x) {
        return (int) right;
    } else {
        return (int) left;
    }
}

17. 一个升序链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素

public ListNode deleteDuplicates(ListNode head) {
    ListNode dummy = new ListNode(0);
    dummy.next = head;
    ListNode pre = dummy;
    ListNode p = head;
    while (p != null && p.next != null) {
      if (p.val == p.next.val) {
        while (p.next != null && p.val == p.next.val) {
          p = p.next;
        }
        pre.next = p.next;
        p = p.next;
      } else {
        pre = p;
        p = p.next;
      }
    }
    return dummy.next;
  }

18.二叉树的最大路径和(节点可为负)?

public int maxPathSum(TreeNode root) {
      int max = Integer.MIN_VALUE;
      process(root,max);
      return max;
    }
    public int process(TreeNode root,int max) {
      if (root == null)
        return 0;
      int left = Math.max(process(root.left), 0);
      int right = Math.max(process(root.right), 0);
      max = Math.max(max, left + right + root.val);
      return root.val + Math.max(left, right);
    }

19.判断二叉树是否对称?

public boolean isSymmetric(TreeNode root) {
    return compare(root, root);
  }

  public boolean compare(TreeNode node1, TreeNode node2) {
    if (node1 == null && node2 == null) {
      return true;
    }
    if (node1 == null || node2 == null) {
      return false;
    }
    if (node1.val != node2.val) {
      return false;
    }
    return compare(node1.left, node2.right) && compare(node1.right, node2.left);
  }

20.找出所有根节点到叶子节点路径和为sum的路径?

public ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) {
    ArrayList<ArrayList<Integer>> result = new ArrayList<>();
    if (root == null) {
      return result;
    }
    dfs(result, new ArrayList<>(), root, sum);
    return result;
  }

  private void dfs(ArrayList<ArrayList<Integer>> result, ArrayList<Integer> list, TreeNode root, int sum) {
    if (root == null) {
      return;
    }
    if (root.left == null && root.right == null) {
      if (sum - root.val == 0) {
        list.add(root.val);
        result.add(new ArrayList<>(list));
        list.remove(list.size() - 1);
      }
      return;
    }
    list.add(root.val);
    dfs(result, list, root.left, sum - root.val);
    dfs(result, list, root.right, sum - root.val);
    list.remove(list.size() - 1);
  }

21. 二叉树中是否存在节点和为指定值的路径?

public boolean hasPathSum (TreeNode root, int sum) {
        if(root == null){
            return false;
        }
        if(root.left == null && root.right == null){
            return (sum - root.val == 0);
        }
 return hasPathSum(root.left,sum - root.val) || hasPathSum(root.right,sum - root.val);
    }

22.集合的所有子集?

public ArrayList<ArrayList<Integer>> subsets(int[] nums) {
    Arrays.sort(nums);
    ArrayList<ArrayList<Integer>> ans = new ArrayList<>();
    ans.add(new ArrayList<Integer>());
    get_ans(nums, 0, new ArrayList<Integer>(), ans);
    return ans;
  }

  public void get_ans(int[] nums, int start, ArrayList<Integer> temp, ArrayList<ArrayList<Integer>> ans) {
    if (start >= nums.length)
      return;
    temp.add(nums[start]);
    ans.add(new ArrayList<>(temp));
    get_ans(nums, start + 1, temp, ans);
    temp.remove(temp.size() - 1);
    get_ans(nums, start + 1, temp, ans);
  }

23. 查找字符串数组中的最长公共前缀?

public String longestCommonPrefix(String[] strs) {
    if (strs.length == 0 || strs == null) {
      return "";
    }
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < strs[0].length(); i++) {
      char ch = strs[0].charAt(i);
      for (int j = 1; j < strs.length; j++) {
        if (strs[j].length() <= i || ch != strs[j].charAt(i)) {
          return sb.length() == 0 ? "" : sb.toString();
        }
      }
      sb.append(ch);
    }
    return sb.toString();
  }

24. 旋转有序数组的二分查找?

java 基础算法题 java的算法题_java

int BSearch(int arr[], int len, int X){
    int left = 0, right = len - 1;
    int m;
    while (left <= right){                  //循环条件
      m = (left + right) / 2;
      if (arr[m] == X)   return m;     //找到了,终止
      if (arr[m] < arr[right]){               //右侧有序
        if (arr[m] < X && arr[right] >= X){
          left = m + 1;
        }
        else right = m - 1;
      }
      else{             //左侧有序
        if (arr[m] > X && arr[left] <= X){
          right = m - 1;
        }
        else  left = m + 1;
      }
    }
    return -1;         //循环结束,没找到。
  }

25、有一个数组,其中第 i 个元素是股票在第i 天的价格,计算可以获得的最大收益

public int maxProfit(int[] prices) {
    if (null == prices || prices.length == 0) {
      return 0;
    }
    int profit = 0, buy = prices[0];
    for (int i = 1; i < prices.length; i++) {
      buy = Math.min(buy, prices[i]);
      profit = Math.max(profit, prices[i] - buy);
    }
    return profit;
  }

26、求链表环的入口(包含多个环的情况)?

a、第一步,找环中相汇点。分别用fast,slow指向链表头部,slow每次走一步,fast每次走二步,直到fastslow找到在环中的相汇点。
b、第二步,找环的入口。接上步,当fast
slow时,fast所经过节点数为2x,slow所经过节点数为x,设链表有n个节点,fast比slow多走一圈有2x=n+x; n=x;
此时n-x即为slow还要走的距离就是入口,将fast 重新赋值为开头,再次重合的地点就是入口

public ListNode EntryNodeOfLoop2(ListNode pHead) {
    ListNode fast = pHead;
    ListNode slow = pHead;
    while (fast != null && fast.next != null) {
      fast = fast.next.next;
      slow = slow.next;
      if (fast == slow) {// 当快指针 与 慢指针相遇时
        fast = pHead;
        while (fast != slow) {// 再次相遇
          fast = fast.next;
          slow = slow.next;
        }
        return fast;
      }
    }
    return null;
  }

27、二分查找

public static int binarySearch(int[] arr, int num) {
    int min = 0;
    int max = arr.length - 1;
    int mid = 0;
    while (min <= max) {
      mid = (min + max) / 2;
      if (num < arr[mid]) {
        max = mid - 1;
      } else if (num > arr[mid]) {
        min = mid + 1;
      } else {
        return mid;// 找到了
      }
    }
    return -1;// 未找到
  }

28、快速排序

public static void quickSort(int[]numbers,int start,int end){
    if(start < end){
      int i = start;
      int j = end;
      int base = numbers[start];
      do{
        while(numbers[i] < base && i < end){
          i++;
        }
        while(numbers[j] > base && j > start){
          j--;
        }
        if(i <= j){
          swap(numbers,i,j);
          j--;
          i++;
        }
      }while(i <= j);
      if(start < j){
        quickSort(numbers,start,j);
      }
      if(i < end){
        quickSort(numbers,i,end);
      }
    }
  }

29、合并有序数组?

输入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]
public static void merge(int A[], int m, int B[], int n) {
    int indexA = m - 1;
    int indexB = n - 1;
    int index = m + n - 1;
    while (indexA >= 0 && indexB >= 0) {
      A[index--] = A[indexA] >= B[indexB] ? A[indexA--] : B[indexB--];
    }
    while (indexB >= 0) {
      A[index--] = B[indexB--];
    }
  }

下面是把两个数组合并到一个新的数组中:

public static int[] merge(int[] arr1, int[] arr2) {
    int i = 0;
    int j = 0;
    int k = 0;
    int len = arr1.length + arr2.length;
    int[] arr = new int[len];
    while(i<arr1.length && j<arr2.length) {
        if(arr1[i]<=arr2[j]) {
            arr[k++] = arr1[i++];
        }else {
            arr[k++] = arr2[j++];
        }
    }
    if(i==arr1.length && j<arr2.length) {
        while(j<arr2.length) {
            arr[k++] = arr2[j++];
        }
    }
    if(j==arr2.length && i<arr1.length) {
        while(i < arr1.length) {
            arr[k++] = arr1[i++];
        }
    }
    return arr;
  }

30、求二进制数中1的个数?

public static int bitCount(int n){
    int count = 0;
    while(n != 0){
        count += n & 1;
        n >>>= 1;
    }
    return count;
}