文章目录
- 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. 旋转有序数组的二分查找?
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、第二步,找环的入口。接上步,当fastslow时,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;
}