最长公共子序列
public int lcs(String s1, String s2) { int len1 = s1.length(); int len2 = s2.length(); int[][] dp = new int[len1 + 1][len2 + 1]; for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (s1.charAt(i - 1) == s2.charAt(j - 1)) { dp[i][j] = dp[i - 1][j - 1] + 1; }else{ dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); } } } return dp[len1][len2]; }
可参考:https://blog.csdn.net/qq_31881469/article/details/77892324
最长公共子串
public int lcs1(String s1, String s2) { int len1 = s1.length(); int len2 = s2.length(); int[][] dp = new int[len1 + 1][len2 + 1]; int max = 0; for (int i = 1; i <= len1; i++) { for (int j = 1; j <= len2; j++) { if (s1.charAt(i - 1) == s2.charAt(j - 1)) { dp[i][j] = dp[i - 1][j - 1] + 1; }else{ dp[i][j] = 0; } max = Math.max(dp[i][j], max); } } return max; }
最长上升子序列
public int lengthOfLIS(int[] nums) { if(nums == null || nums.length == 0) return 0; int[] dp = new int[nums.length]; int max = 1; Arrays.fill(dp, 1); for (int i = 0; i < nums.length; i++) { for (int j = 0; j < i; j++) { if (nums[j]<nums[i]){ dp[i] = Math.max(dp[i],dp[j] + 1); } } max = Math.max(dp[i], max); } return max; }
最长连续上升子序列
public int findLengthOfLCIS(int[] nums) { if(nums == null || nums.length < 1) return 0; int[] dp = new int[nums.length]; int max = 1; Arrays.fill(dp, 1); for (int i = 1; i < nums.length; i++) { if (nums[i] > nums[i - 1]) { dp[i] = dp[i-1]+1; } max = Math.max(dp[i], max); } return max; }
最长公共前缀
public String longestCommonPrefix(String[] strs) { if (strs.length == 0) return ""; String prefix = strs[0]; for (int i = 1; i < strs.length; i++) while (strs[i].indexOf(prefix) != 0) { prefix = prefix.substring(0, prefix.length() - 1); if (prefix.isEmpty()) return ""; } return prefix; }
最大子序列和
public int maxSubArray(int[] nums) { if(nums == null || nums.length == 0) return 0; int max = nums[0],sum = 0; for(int i = 0; i < nums.length ; i++){ if(sum > 0 ){ sum += nums[i]; }else{ sum = nums[i]; } max = Math.max(sum,max); } return max; }
无重复字符的最长子串
public static int lengthOfLongestSubstring(String s) { Map<Character, Integer> map = new HashMap<>(); int max = 0; int start = 0; for(int end = 0;end <s.length();end++) { char c = s.charAt(end); if (map.containsKey(c)) { // 这里必须使用max函数,防止出现输入字符串是abba的这种情况,在最后一次发现a在map中的时候 // 查到的结果为map.get(c)=0,那么start= map.get(c)+1就是1,最后的结果为3,使用max函数 // 就是为了防止start指针后退。 start = Math.max(start, map.get(c)+1); } map.put(c, end); max = Math.max(max, end - start + 1); } return max; }
大数相加
可以参考我的这篇文章 大数相加,大数相乘,下面的重新写的代码没有进行多次翻转,相对简单
public static String add(String s1,String s2) { String res = ""; int len1 = s1.length(); int len2 = s2.length(); int max = len1>len2?len1:len2; // 用0补齐到相同长度,方便计算 if(len1 < len2) { for (int i = 0; i < max - len1; i++) { s1 = "0" + s1; } }else { for (int i = 0; i < max - len2; i++) { s2 = "0" + s2; } } int c = 0;//进位 for (int i = max - 1; i >= 0; i--) { // 减0是可以直接拿到数字大小 int temp = (s1.charAt(i) - '0') + (s2.charAt(i) - '0') + c; int cur = temp % 10;//这是进位后的个位数 res = cur + res;//将这个数添加到结果中 c = temp / 10;//进位 } if(c>0) {//判断最后是否有进位大于0,如果有添加 res = c + res; } return res;//反转输出 }
大数相乘
链表大数相加
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode head = new ListNode(0); ListNode cur = head,p1=l1,p2=l2; int carry = 0; while(p1 != null || p2 != null ){ int x = p1!=null?p1.val:0; int y = p2!=null?p2.val:0; int sum = x+y+carry; carry = sum/10; cur.next = new ListNode(sum%10); cur = cur.next; if(p1!=null) p1 = p1.next; if(p2!=null) p2 = p2.next; } if(carry >0 ){ cur.next = new ListNode(carry); } return head.next; }
两数之和
public int[] twoSum(int[] nums,int target){ HashMap<Integer,Integer> map = new HashMap<>(); for(int i = 0;i<nums.length;i++){ int tmp = target - nums[i]; if(map.containsKey(tmp)){ return new int[]{map.get(tmp),i}; } map.put(nums[i],i); } return new int[2]; }
删除有序链表中的重复元素(只保留一个重复元素)
public ListNode deleteDuplicates(ListNode head) { ListNode phead = new ListNode(0); phead.next = head; ListNode slow = phead,fast = head; while(fast!=null){ while(fast.next != null && fast.val == fast.next.val) fast = fast.next; slow.next = fast; slow = slow.next; fast = fast.next; } return phead.next; }
数组去重
不考虑最终数组拍完序的数组元素,例如1,1,3,2,2,2,2,2,5,最终去重后数组的元素为1,3,2,5,2,2,2,2,5
public void deleteDup(int[] nums) { if (nums == null || nums.length == 0) return; int fast = 0; int slow = 0; while (fast < nums.length) { while (fast + 1 < nums.length && nums[fast] == nums[fast + 1]) fast++; nums[slow++] = nums[fast++]; } }
一个数组奇偶分开,偶数在前奇数在后(不要求相对有序)
可参考我的这篇文章给一个数组,把偶数放到左边,奇数放到右边(有序和无序)
public void reOrderArray(int[] nums) { int less = 0; int more = nums.length-1; while (less < more) { while (nums[more] % 2 == 0) { swap(nums, more, less++); } more--; } } public void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; }
一个数组奇偶分开,偶数在前奇数在后(要求变换前后相对有序)
public void reOrderArray(int[] array) { if ( array == null || array.length == 0 ) return; int left = 0;//从左向右最右边的奇数下标 for (int i = 0; i < array.length; i++) { if (array[i] % 2 == 0) { int cur = i;//碰到的偶数 while (cur > left) {//逐个交换位置 swap(array, cur, --cur); } left++;//交换完偶数下标向右移动 } } } public void swap(int[] arr, int i, int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; }
数组中除了两个数都只出现一次,其余的都只出现一次
数组topK
public int topK(int[] nums, int k) { if (nums == null || k <0 || k>nums.length) return Integer.MIN_VALUE; PriorityQueue<Integer> queue = new PriorityQueue<>(k); for (int i = 0; i < nums.length; i++) { if (queue.size() == k) { if (queue.peek() < nums[i]) { queue.poll(); queue.offer(nums[i]); } }else { queue.offer(nums[i]); } } int res = queue.peek(); for (int item : queue) { res = queue.poll(); } return res; }
全排列
两个二叉树是否相等
二叉树最大值
二叉树第K大
树的前序中序后序递归非递归遍历
树变链表
快排,归并,冒泡
二分查找递归非递归
桶排序
凑硬币
01背包
括号匹配
进制转换
public String transter(int m, int n) { StringBuilder sb = new StringBuilder(); boolean flag = true; if (m < 0) { m = -m; flag = false; } while (m > 0) { int yu = m % n; if (yu > 9) { char temp = (char) (yu - 10 + 'A'); sb.append(temp); }else { sb.append(yu); } m = m / n; } if (!flag) { sb.append("-"); } return sb.reverse().toString(); }
来源:51CTO
作者:Hollake
链接:https://blog.csdn.net/Hollake/article/details/100642464