zoukankan      html  css  js  c++  java
  • LeetCode1-5

    Leetcode1:

    Given an array of integers, return indices of the two numbers such that they add up to a specific target.

    You may assume that each input would have exactly one solution, and you may not use the same element twice.

    题意:给定一个整数数组,返回两个数下标满足和等于一个特定的数;假设不存在相同的元素和得到的解只有一个;

    例子:数组:[2, 7, 11,15],目标值为 9, 因为 nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

    思路:方法一:通过hashmap额外的存储空间---时间复杂度和空间复杂度都是O(n)

     1 private static int[] addSum1(int[] aa, int target) {
     2         Map<Integer, Integer> map = new HashMap<>();
     3         for (int i = 0; i < aa.length; i++) {
     4             map.put(aa[i], i);
     5         }
     6         for (int i = 0; i < aa.length; i++) {
     7             int complete = target - aa[i];
     8             // 如果map中包含差值 且不是当前的值
     9             if (map.containsKey(complete) && map.get(complete) != i) {
    10                 return new int[]{map.get(complete), i};
    11             }
    12         }
    13         return null;
    14     }

    方法二:时间复杂度高,迭代尝试

     1  // 方法1 迭代尝试 时间复杂度比较高
     2     private static int[] addSum(int[] aa, int target) {
     3         for (int i = 0; i < aa.length; i++) {
     4             for (int j = i + 1; j < aa.length; j++) {
     5                 if (aa[i] == target - aa[j]) {
     6                     return new int[]{i, j};
     7                 }
     8             }
     9         }
    10         return null;
    11     }

    Leetcode 2 :

    You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

    You may assume the two numbers do not contain any leading zero, except the number 0 itself.

    例子:输入: (2 -> 4 -> 3) + (5 -> 6 -> 4)
              输出: 7 -> 0 -> 8
              结果: 342 + 465 = 807.

    题意:将链表的对应节点进行相加,计算出来的结果构成新的链表;

    思路:通过新建一个链表,首节点是一个虚拟的节点,然后返回虚拟节点的后面的节点;

     1 public static ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
     2         ListNode listNode = new ListNode(0);
     3         ListNode result = listNode;
     4         ListNode p1 = l1;
     5         ListNode p2 = l2;
     6         int cad = 0;
     7         while (p1 != null || p2 != null) {        
     8             int aa = (p1 == null ? 0: p1.val) +(p2 == null?0:p2.val) + cad;
     9             listNode.next = new ListNode(aa % 10);
    10             cad = aa / 10;
    11             listNode = listNode.next;
    12             if (p1 != null) {
    13                 p1 = p1.next;
    14             }
    15             if (p2 != null) {
    16                 p2 = p2.next;
    17             }
    18         }
    19         if (cad != 0) {
    20             listNode.next = new ListNode(cad);
    21         }
    22 
    23         return result.next;
    24     }
    View Code

    Leetcode 3 :

    Given a string, find the length of the longest substring without repeating characters.

    题意:给定一个字符串,找到不含重复元素的子串的最大长度;

    思路:

     1 public static int lengthOfLongestSubstring(String s) {
     2         int k = 0;
     3         int res = 0;
     4         char[] array = s.toCharArray();
     5         HashSet<Character> hashSet = new HashSet<>();
     6         for (int i = 0; i < array.length; i++) {
     7             if (!hashSet.contains(array[i])) {
     8                 // 如果set中不存在这个值 就将他加入 并更新结果值
     9                 hashSet.add(array[i]);
    10                 res = Math.max(res, hashSet.size());
    11             } else {
    12                 // 如果存在 将重复元素的前面部分去掉 取重复元素的下一个
    13                 while (k < i) {
    14                     if (s.charAt(k) == array[i]) {
    15                         k++;
    16                         break;
    17                     } else {
    18                         hashSet.remove(array[k]);
    19                         k++;
    20                     }
    21                 }
    22             }
    23         }
    24         return res;
    25     }
    26 
    27     public static int lengthOfLongestSubstring1(String s) {
    28         int length = s.length();
    29         if (length == 0) {
    30             return 0;
    31         }
    32         int[] countTable = new int[256];
    33         Arrays.fill(countTable, -1);
    34         int max = 1;
    35         int start = 0;
    36         int end = 1;
    37         countTable[s.charAt(0)] = 0;
    38         while (end < length) {
    39             // Has not reached a duplicate char
    40             if (countTable[s.charAt(end)] >= start) {
    41                 start = countTable[s.charAt(end)] + 1;
    42             }
    43             max = Math.max(max, end - start + 1);
    44             countTable[s.charAt(end)] = end;
    45             end++;
    46         }
    47         return max;
    48     }
    49 
    50     public static int lengthOfLongestSubstring2(String s) {
    51         int n = s.length(), ans = 0;
    52         int[] index = new int[128];
    53         for (int j = 0, i = 0; j < n; j++) {
    54             System.out.println(s.charAt(j) + "..");
    55             System.out.println(index[s.charAt(j)] + "....");
    56             i = Math.max(index[s.charAt(j)], i);//返回该字符第一次重复出现的位置
    57             System.out.println("i:"+i);
    58             ans = Math.max(ans, j - i + 1);//返回字符的长度
    59             index[s.charAt(j)] = j + 1;//记录该字符在字符串中的位置
    60         }
    61         return ans;
    62     }
    View Code

    Leetcode 4 :

    There are two sorted arrays nums1 and nums2 of size m and n respectively.

    Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

    You may assume nums1 and nums2 cannot be both empty.

    题意:在两个有序数组中,寻找中位数。要求运行时间在O(log (m+n)),假设连个数组都不同时为空;

    思路:将两个数组排序成一个有序的数组,如果为偶数,去中间两个数的平均值;如果为奇数,直接去中间的数;

      //O(nlogn)
     1 public static double findMedianSortedArrays(int[] nums1, int[] nums2) {
     2         int m = nums1.length;
     3         int n = nums2.length;
     4         //当两个数组都是空的时候
     5         if (m == 0 && n == 0) {
     6             return 0;
     7         }
     8         //当其中一个数组为空时
     9         if (m == 0) {
    10             return getMidVal(nums2, n);
    11         }
    12         if (n == 0) {
    13             return getMidVal(nums1, m);
    14         }
    15         int[] res = new int[m + n];
    16         int j = 0;
    17         int k = 0;
    18         for (int i = 0; i < res.length; i++) {
    19             //当其中一个数组为空时 另一个还未空时
    20             if (j == m && k != n) {
    21                 res[i] = nums2[k++];
    22                 continue;
    23             }
    24             if (k == n && j != m) {
    25                 res[i] = nums1[j++];
    26                 continue;
    27             }
    28             //当两个都没空时
    29             if (nums1[j] < nums2[k]) {
    30                 res[i] = nums1[j];
    31                 j++;
    32             } else {
    33                 res[i] = nums2[k];
    34                 k++;
    35             }
    36         }
    37         //根据奇偶数取中位数
    38         return getMidVal(res, m + n);
    39     }
    40 
    41     private static double getMidVal(int[] nums2, int n) {
    42         if (n % 2 == 0) {
    43             return (double) (nums2[n / 2 - 1] + nums2[n / 2]) / 2;
    44         } else {
    45             return nums2[n / 2];
    46         }
    47     }

    问题转换为求两个数组中第K个小的元素.

    首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。

    当A[k/2-1]>B[k/2-1]时存在类似的结论。

    当A[k/2-1]=B[k/2-1]时,我们已经找到了第k小的数,也即这个相等的元素.

    • 如果A或者B为空,则直接返回B[k-1]或者A[k-1];
    • 如果k为1,我们只需要返回A[0]和B[0]中的较小值;
    • 如果A[k/2-1]=B[k/2-1],返回其中一个;
     1 public class Solution {
     2     public static double findKth(int a[],int begina,int m,int b[],int beginb,int n,int k){
     3         if(m>n)              //确保函数m<=n
     4             return findKth(b,beginb,n,a,begina,m,k);
     5         if(m==0)
     6             return b[beginb+k-1];
     7         if(k==1)
     8             return Math.min(a[begina],b[beginb]);
     9         int ma = Math.min(k / 2, m), mb = k - ma;  //把k分成两部分
    10         if(a[begina+ma-1]<b[beginb+mb-1])        //把a数组前面ma个元素去掉,第k小的元素不在这里
    11             return  findKth(a,begina+ma,m-ma,b,beginb,n,k-ma);
    12         else if(a[begina+ma-1]>b[beginb+mb-1])   //把b数组前面mb个元素去掉,第k小的元素不在这里
    13             return  findKth(a,begina,m,b,beginb+mb,n-mb,k-mb);
    14         else return a[begina+ma-1];              //相等时就是它
    15 
    16     }
    17     public static double findMedianSortedArrays(int A[], int B[]) {
    18         int m=A.length;
    19         int n=B.length;
    20         int totalLength=m+n;
    21         if (totalLength%2 == 1)      //奇数长度
    22             return findKth(A, 0, m, B, 0, n, totalLength/2+1);
    23         else {                           //偶数长
    24             return (findKth(A, 0, m, B, 0, n, totalLength / 2) + findKth(A, 0, m, B, 0, n, totalLength / 2 + 1)) / 2;
    25         }
    26     }
    27     public static void main(String[] args){
    28         int[] a={3};
    29         int[] b={1,2};
    30         double median=findMedianSortedArrays(a,b);
    31         System.out.println(median);
    32 
    33     }
    34 }

    Leetcode 5 : 最长回文子串

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

    思路 动态规划

      1 // 动态规划
      2     public static String findLongestPalindrome1(String s) {
      3         if (s == null || s.length() == 0 || s.length() == 1) {
      4             return s;
      5         }
      6         int len = s.length();
      7         int start = 0;
      8         int maxlength = 0;
      9         boolean p[][] = new boolean[s.length()][s.length()];
     10         // 子串长度为1和为2的初始化
     11         for (int i = 0; i < len; i++) {
     12             p[i][i] = true;
     13             if (i < len - 1 && s.charAt(i) == s.charAt(i + 1)) {
     14                 p[i][i + 1] = true;
     15                 start = i;
     16                 maxlength = 2;
     17             }
     18         }
     19         // 使用上述结果可以dp出子串长度为3~len -1的子串
     20         for (int strlen = 3; strlen <= len; strlen++) {
     21             for (int i = 0; i <= len - strlen; i++) {
     22                 int j = i + strlen - 1; // 子串结束的位置
     23                 if (p[i + 1][j - 1] && s.charAt(i) == s.charAt(j)) {
     24                     p[i][j] = true;
     25                     maxlength = strlen;
     26                     start = i;
     27                 }
     28             }
     29         }
     30         if (maxlength > 0)
     31             return s.substring(start, start + maxlength);
     32         return new String(s.substring(0, 1));
     33     }
     34 
     35     // 中心扩展法
     36     public String longestPalindrome(String s) {
     37         if (s == null || s.length() == 0 || s.length() == 1) {
     38             return s;
     39         }
     40         int len = s.length();
     41         int maxlength = 0;
     42         int start = 0;
     43         // 类似于aba这种情况,以i为中心向两边扩展
     44         for (int i = 0; i < len; i++) {
     45             int j = i - 1;
     46             int k = i + 1;
     47             while (j >= 0 && k < len && s.charAt(j) == s.charAt(k)) {
     48                 if (k - j + 1 > maxlength) {
     49                     maxlength = k - j + 1;
     50                     start = j;
     51                 }
     52                 j--;
     53                 k++;
     54             }
     55         }
     56         // 类似于abba这种情况,以i,i+1为中心向两边扩展
     57         for (int i = 0; i < len; i++) {
     58             int j = i;
     59             int k = i + 1;
     60             while (j >= 0 && k < len && s.charAt(j) == s.charAt(k)) {
     61                 if (k - j + 1 > maxlength) {
     62                     maxlength = k - j + 1;
     63                     start = j;
     64                 }
     65                 j--;
     66                 k++;
     67             }
     68         }
     69         if (maxlength > 0)
     70             return s.substring(start, start + maxlength);
     71         return new String(s.substring(0, 1));
     72     }
     73 
     74     // Manacher算法
     75     public static String findLongestPalindrome3(String s) {
     76         if (s == null || s.length() < 1)
     77             return s;
     78         String str = dealWithS(s); // 处理一下s,即将给字符串s的中间加上特殊字符,这样无论对于奇数字符还是偶数字符可以做同样的处理
     79         int[] res = new int[str.length()];
     80         int R = 0; // 当前所能扩展的半径
     81         int C = 0; // C位置的半径为R
     82         int maxC = 0; // 最长的半径的位置
     83         res[0] = 0;
     84         for (int i = 1; i < str.length(); i++) {
     85             int j = 2 * C - i; // i点的对称点
     86             if (j >= 0 && res[j] < R - i) // 对称点存在且对称点的回文半径在C的回文中
     87             {
     88                 res[i] = res[j];
     89             } else // 否则,需要根据i点一点一点的计算
     90             {
     91                 int k = 1;
     92                 while (R + k < str.length() && 2 * i - R - k >= 0) {
     93                     if (str.charAt(R + k) == str.charAt(2 * i - R - k))
     94                         k++;
     95                     else
     96                         break;
     97                 }
     98                 res[i] = R - i + k - 1;
     99                 if (res[i] + i > R) {
    100                     R = res[i] + i;
    101                     C = i;
    102                 }
    103             }
    104 
    105             maxC = res[maxC] > res[i] ? maxC : i; // maxC保存的是回文半径最大的那个点的位置
    106         }
    107         String subStr = str.substring(maxC - res[maxC], maxC + res[maxC] + 1);
    108         StringBuffer sb = new StringBuffer();
    109         for (int i = 0; i < subStr.length(); i++) {
    110             if (subStr.charAt(i) != '#')
    111                 sb.append(subStr.charAt(i));
    112         }
    113         return sb.toString();
    114     }
    115 
    116     public static String dealWithS(String s) // 将原字符串进行处理
    117     {
    118         StringBuffer sb = new StringBuffer();
    119         sb.append("#");
    120         for (int i = 0; i < s.length(); i++) {
    121             sb.append(s.charAt(i));
    122             sb.append("#");
    123         }
    124         return sb.toString();
    125     }
    View Code
  • 相关阅读:
    <爬虫实例> 8684公交网-太原公交线路信息
    <爬虫> requests模块
    爬虫四 selenium + phantomjs & Headless Chrome
    爬虫三 bs4&xpath&jsonpath
    爬虫二 cookie&正则
    爬虫一 发请求&定制请求&异常处理&配置代理
    抽屉页面设计
    HTML标签及其属性
    Python之路 day3 高阶函数
    Python之路 day3 递归函数
  • 原文地址:https://www.cnblogs.com/ntbww93/p/9683250.html
Copyright © 2011-2022 走看看