zoukankan      html  css  js  c++  java
  • LeetCode

    1、两数之和:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。

    2、两数相加:给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。

    3、无重复字符的最长子串:给定一个字符串,找出不含有重复字符的最长子串的长度。

    4、两个排序数组的中位数

    5、最长回文子串:遍历字符串,从每个字符开始,往左右遍历看左右是否相等,相等继续往外扩散

    6、Z字形变换

    7、反转整数:除以10取余,取商注意负数、及溢出情况

    8、回文数:判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数:注意负数;1、先转字符串再判断;2、反转一半数字

    11、盛最多水的容器:给定 n 个非负整数 a1a2,...,an,每个数代表坐标中的一个点 (iai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (iai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

         双指针法,一个指向开始,一个指向结尾,往中间移动

    14、最长公共前缀:编写一个函数来查找字符串数组中的最长公共前缀。先遍历字符串数组,找出最短的字符串,遍历最短的字符串,和其他字符串一一比较;

    15、三数之和:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

           先排序,遍历数组,以当前数为目标值,从当前数的后一个数开始,到最后一个之间查找两个数与目标值相加=0的数,如果大于0,则右边的下标左移,如果小于0,则左边的下标右移,直到右边的下标大于等于左边的下标,结束当前的查找,其实相当于第一题。

    16、最接近的三数之和:给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

           同上题, 先排序,遍历数组,以当前数为目标值,从当前数的后一个数开始,到最后一个之间查找两个数与目标值相加接近target 的数,如果大于target ,则右边的下标左移,如果小于target ,则左边的下标右移,直到右边的下标大于等于左边的下标,结束当前的查找

    18、四数之和四数之和:给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

           同上题,先排序,遍历数组,两个for循环

    19、删除链表的倒数第N个节点:2个指针,一个先走N步后,另一个指针从头结点开始,当第一个指针走到最后,另一个节点走到倒数第N个

    20、有效的括号:给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。用LinkedList或者数组实现栈

    21、合并两个有序链表:将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

    23、合并K个排序链表:合并 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。递归:分一半,然后合并2个链表

    24、两两交换链表中的节点:给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。注意头节点,使用两个指针指向待交换节点,注意判断最后两个尾节点是否为null

    25、k个一组翻转链表:

    给出一个链表,每 个节点一组进行翻转,并返回翻转后的链表。

    是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 的整数倍,那么将最后剩余节点保持原有顺序。

    26、删除排序数组中的重复项

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

    不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

    count用于统计个数,作为结待排下标设置结果,cur设置当前值,用于比较下一个值是否相等,不相等则设置结果

    27、移除元素

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

    不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。

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

    同上;

    28、实现strStr()

    给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1

        int i=0,j=0;
            while(i<len_s&&j<len_t){
                if(haystack.charAt(i)==needle.charAt(j)){
                    i++;
                    j++;
                }else {
                    if((len_s-i-1)<len_t-j)
                        return -1;
                    i=i-j+1;
                    j=0;
                }
            }
            return i-j;

    30、与所有单词相关联的字串

    给定一个字符串 和一些长度相同的单词 words。 s 中找出可以恰好串联 words 中所有单词的子串的起始位置。

    注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

    public class Solution {
        public List<Integer> findSubstring(String s, String[] words) {
           List<Integer> list = new ArrayList<Integer>();
                int len=words.length;
                int len_s=s.length();
                int len_word=words[0].length();
                
                Map<String, Integer> map=new HashMap<String, Integer>();
                for (int i = 0; i < len; i++) {
                    if(map.containsKey(words[i])){
                        map.put(words[i], map.get(words[i])+1);
                    }else {
                        map.put(words[i], 1);
                    }
                }
                String string=null;
                for(int i=0;i<=len_s-len*len_word;i++){
                    int count=0;
                    int begin=i;
                    string=s.substring(begin, begin+len_word);
                    while(map.containsKey(string)&&map.get(string)>0){
                        map.put(string, map.get(string)-1);
                        count++;
                        begin+=len_word;
                        if(begin+len_word>len_s){
                            break;
                        }
                        string=s.substring(begin, begin+len_word);
                    }
                    if(count==len){
                        list.add(i);
                    }
                    if(count>0){
                        map.clear();
                        for (int j = 0; j < len; j++) {
                            if(map.containsKey(words[j])){
                                map.put(words[j], map.get(words[j])+1);
                            }else {
                                map.put(words[j], 1);
                            }
                        }
                    }
                }
                return list;
        }
    }

    31、下一个排列

    实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。

    如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。

    必须原地修改,只允许使用额外常数空间。

    以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
    1,2,31,3,2
    3,2,11,2,3
    1,1,51,5,1

    public class Solution {
        public void nextPermutation(int[] nums) {
            int i = nums.length - 2;
    //从右向左找第一个正序
    while (i >= 0 && nums[i + 1] <= nums[i]) { i--; }
    //从右向左找第一个比nums[i]大的数
    if (i >= 0) { int j = nums.length - 1; while (j >= 0 && nums[j] <= nums[i]) { j--; } swap(nums, i, j); }
    //i后面的数反转 reverse(nums, i
    + 1); } private void reverse(int[] nums, int start) { int i = start, j = nums.length - 1; while (i < j) { swap(nums, i, j); i++; j--; } } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } }

    32、最长有效括号

    给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

    public class Solution {
        public int longestValidParentheses(String s) {
            int len=0;
            int [] aa=new int[s.length()];
            for(int i=0;i<s.length();i++){
                if(s.charAt(i)=='(') aa[i]=0;
                else {
                    int pre=i-1;
                    while(pre>=0&&aa[pre]>0){
                        pre-=aa[pre];
                    }
                    
                    if(pre>=0&&s.charAt(pre)=='('){
                        aa[i]=i-pre+1;
                        if(pre>0){
                            aa[i]+=aa[pre-1];
                        }
                    }
                    
                }
                len=Math.max(len, aa[i]);
            }
            return len;
        }
    }

    34、在排序数组中查找元素的第一个和最后一个位置

    给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。

    你的算法时间复杂度必须是 O(log n) 级别。

    如果数组中不存在目标值,返回 [-1, -1]

    35、搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

    你可以假设数组中无重复元素。

    36、有效的数独

    判断一个 9x9 的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。

    1. 数字 1-9 在每一行只能出现一次。
    2. 数字 1-9 在每一列只能出现一次。
    3. 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。

      三个List<Set<Character>> r=new ArrayList<Set<Character>>();

    38、

    报数序列是指一个整照其中的整数的顺序进数序列,按行报数,得到下一个数。其前五项如下:

    1.     1
    2.     11
    3.     21
    4.     1211
    5.     111221
    

    1 被读作  "one 1"  ("一个一") , 即 11
    11 被读作 "two 1s" ("两个一"), 即 21
    21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211

    给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。

    注意:整数顺序将表示为一个字符串。

    public class Solution {
        public String countAndSay(int n) {
           if (n == 1)
                return "1";
    
            String str = countAndSay(n - 1)+"*";
            char[] c = str.toCharArray();
            int count = 1;
            String s = "";
            for (int i = 0; i < c.length - 1; i++) {
                if (c[i] == c[i + 1]) {
                    count++;
                } else {
                    s += count + "" + c[i];
                    count = 1;
                }
            }
            return s;
        }
    }

    39. 组合总和

    给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

    candidates 中的数字可以无限制重复被选取。

    public class Solution {
        
         List<List<Integer>> lists = new ArrayList<List<Integer>>();  
        
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            Arrays.sort(candidates);
            backTrackeing(new ArrayList<Integer>(),candidates,0, target);
            return lists;
        }
        
        private  void backTrackeing(ArrayList<Integer> cur,
                int[] candidates, int from, int target) {
            if(target==0){
                List<Integer> list=new ArrayList<Integer>(cur);
                lists.add(list);
            }else {
                for(int i=from;i<candidates.length&&candidates[i]<=target;i++){
                    cur.add(candidates[i]);
                    backTrackeing(cur, candidates, i, target-candidates[i]);
                    cur.remove(new Integer(candidates[i]));
                }
            }
        }
    }

    40. 组合总和 II

    给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

    candidates 中的每个数字在每个组合中只能使用一次。

    说明:

    • 所有数字(包括目标数)都是正整数。
    • 解集不能包含重复的组合。
    同上,递归从i+1开始

    41. 缺失的第一个正数

    给定一个未排序的整数数组,找出其中没有出现的最小的正整数。

    public class Solution {
        public int firstMissingPositive(int[] nums) {
            for (int i = 0; i < nums.length; i++) {
                while (nums[i] > 0 && nums[i] <= nums.length
                        && nums[nums[i] - 1] != nums[i]) {
                    int tmp = nums[nums[i] - 1];
                    nums[nums[i] - 1] = nums[i];
                    nums[i] = tmp;
                }
            }
    
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] != i + 1)
                    return i + 1;
            }
            return nums.length+1;
        }
    }

    42、接雨水

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

    上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

    示例:

    输入: [0,1,0,2,1,0,1,3,2,1,2,1]
    输出: 6
    public class Solution {
        public int trap(int[] height) {
           int rainV=0;
            int l=0,r=height.length-1;
            while(l<r&&height[l]<=height[l+1]) l++;
            while(l<r&&height[r]<=height[r-1]) r--;
            while(l<r){
                int left=height[l];
                int right=height[r];
                if(left<=right){
                    while(l<r&&left>=height[++l]){
                        rainV+=left-height[l];
                    }
                }else {
                    while(l<r&&right>=height[--r]){
                        rainV+=right-height[r];
                    }
                }
            }
            return rainV;
        }
    }

    从两边开始,左边找后边比前面高度小的,右边找前面比后面高的,左边下标小于右边

     45. 跳跃游戏 II

    给定一个非负整数数组,你最初位于数组的第一个位置。

    数组中的每个元素代表你在该位置可以跳跃的最大长度。

    你的目标是使用最少的跳跃次数到达数组的最后一个位置。

    public class Solution {
        public int jump(int[] A) {
            if(A.length<=1){
                return 0;
            }
            int i=0,j=0;
            int count=0;
            while(i<A.length){
    //注意方法出口
    if(i+A[i]>=A.length-1){ count++; return count; }
    //寻找当前数后面几位中最大的值
    int temp=Integer.MIN_VALUE; for(int k=i+1;k<=i+A[i];k++){ if(temp<k+A[k]){ temp=k+A[k]; j=k; } }
    //从最大值后再继续查找 i
    =j; count++; } return 0; } }

     55、跳跃游戏

    给定一个非负整数数组,你最初位于数组的第一个位置。

    数组中的每个元素代表你在该位置可以跳跃的最大长度。

    判断你是否能够到达最后一个位置。

    public class Solution {
        public boolean canJump(int[] nums) {
            int reach=0;
            int i=0;
            for(;i<nums.length&&i<=reach;i++){
                reach=Math.max(reach,i+nums[i]);
            }
            return (i==nums.length);
        }
    }

    46. 全排列

    给定一个没有重复数字的序列,返回其所有可能的全排列。

    斐波那契计算所有排序的情况数,

    List<List<Integer>> lists=new ArrayList<List<Integer>>();记录结果集

    从右往左找到第一个正序,再从右往左找到第一个比它大的数,交换两个数,再将后面的数反转

    47、全排列 II

    给定一个可包含重复数字的序列,返回所有不重复的全排列。

    public class Solution {
        public void rotate(int[][] matrix) {
            int n=matrix.length;//若n=4
            int count=(n-1)/2;//矩阵有几圈=count+1
            for(int i=0;i<=count;i++){//i=0,1
                for(int j=i;j<n-i-1;j++){//当i=0时,j=0,1,2   当i=1时,j=1
                    int tmp=matrix[i][j];
                    matrix[i][j]=matrix[n-j-1][i];
                    matrix[n-j-1][i]=matrix[n-i-1][n-j-1];
                    matrix[n-i-1][n-j-1]=matrix[j][n-i-1];
                    matrix[j][n-i-1]=tmp;
                }
            }
        }
    }

    49、字母异位词分组

    给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

    public class Solution {
        public List<List<String>> groupAnagrams(String[] strs) {
            List<List<String>> lists=new ArrayList<List<String>>();
            Map<String, List<String>> map=new HashMap<String, List<String>>();
            for(int i=0;i<strs.length;i++){
                char []c=strs[i].toCharArray();
                Arrays.sort(c);
                String str=String.valueOf(c);
                if(!map.containsKey(str)){
                    List<String> list=new ArrayList<String>();
                    map.put(str, list);
                }
                map.get(str).add(strs[i]);
            }
            for(String key:map.keySet()){
                Collections.sort(map.get(key));
                lists.add(map.get(key));
            }
            return lists;
        }
    }

    53. 最大子序和

     给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

    public class Solution {
        public int maxSubArray(int[] nums) {
            int sum=Integer.MIN_VALUE;
            int maxNum=Integer.MIN_VALUE;;
            for(int i=0;i<nums.length;i++){
                if(sum>0){
                    sum+=nums[i];
                }else {
                    sum=nums[i];
                }
                if(sum>maxNum)
                    maxNum=sum;
            }
            return maxNum;
        }
    }

    54. 螺旋矩阵

    给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。

        int top=0,bottom=m-1,left=0,right=n-1;
        int loop=m<n?m:n;
        loop=(loop+1)/2;

    60. 第k个排列

    给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

    按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

    1. "123"
    2. "132"
    3. "213"
    4. "231"
    5. "312"
    6. "321"

    给定 n 和 k,返回第 k 个排列。

    说明:

    • 给定 n 的范围是 [1, 9]。
    • 给定 的范围是[1,  n!]。
    public class Solution {
        public String getPermutation(int n, int k) {
            List<Integer> list=new ArrayList<Integer>();
            int s=1;
            String str="";
            for(int i=1;i<=n;i++){
                list.add(i);
                s*=i;
                
            }
            int a,b;
            k--;
            while(list.size()!=1){
                if(k==0) {
                    for (Integer x : list) {
                        str+=x;
                    }
                    return str;
                }
                a=k/Factorial(n-1);
                k=(k-Factorial(n-1)*a)%Factorial(n-1);
                str+=list.get(a);
                list.remove(a);
                n--;
                
            }
    
            str+=list.get(0);
            return str;
        }
        public  int Factorial(int n){
            if(n==1||n==0)
                return 1;
            else {
                return Factorial(n-1)*n;
            }
        }
    }

    61、旋转链表

    给定一个链表,旋转链表,将链表每个节点向右移动 个位置,其中 是非负数。

    62. 不同路径

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

    机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

    问总共有多少条不同的路径?

    C7,2

    63、不同路径2

    一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

    机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

    现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

    使用二维数组,标记若当前值为1则,标记0;
    
    遍历二维数组,若原数组当前值为1,则记为0,其余均为其上和其左数值之和;
    
    返回最后一个数值;

    64. 最小路径和

    给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

    说明:每次只能向下或者向右移动一步。

    public class Solution {
        public int minPathSum(int[][] grid) {
            int m=grid.length;
            int n=grid[0].length;
            int []ans=new int [n];
            ans[0]=grid[0][0];
            for(int i=1;i<n;i++){
                ans[i]=ans[i-1]+grid[0][i];
            }
            
            for(int i=1;i<m;i++){
                ans[0]+=grid[i][0];
                for(int j=1;j<n;j++){
                    ans[j]=Math.min(ans[j-1], ans[j])+grid[i][j];
                }
            }
            
            return ans[n-1];
        }
    }

    66. 加一

    给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。

    最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。

    你可以假设除了整数 0 之外,这个整数不会以零开头。

    public class Solution {
        public int minPathSum(int[][] grid) {
            int m=grid.length;
            int n=grid[0].length;
            int []ans=new int [n];
            ans[0]=grid[0][0];
            for(int i=1;i<n;i++){
                ans[i]=ans[i-1]+grid[0][i];
            }
            
            for(int i=1;i<m;i++){
                ans[0]+=grid[i][0];
                for(int j=1;j<n;j++){
                    ans[j]=Math.min(ans[j-1], ans[j])+grid[i][j];
                }
            }
            
            return ans[n-1];
        }
    }

    67. 二进制求和

    给定两个二进制字符串,返回他们的和(用二进制表示)。

    输入为非空字符串且只包含数字 1 和 0

    70. 爬楼梯

    假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

    每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

    注意:给定 n 是一个正整数。

    public class Solution {
        public int climbStairs(int n) {
            if (n == 0 || n == 1 || n == 2)
                return n;
            int[] aa = new int[n];
            aa[0] = 1;
            aa[1] = 2;
            for (int i = 2; i < n; i++) {
                aa[i] = aa[i - 1] + aa[i - 2];
            }
            return aa[n - 1];
        }
    }

    73. 矩阵置零

    给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法

    先遍历第一行和第一列,是否存在含0的数据,是则标记;
    
    再遍历数组,用第一行第一列来标记这一行一列是否存在含0的数,是的话置0;
    
    遍历第一行和第一列,将为0的对应的列和行,置为0;
    
    再检验原第一行和第一列是否存在含0数据,是的话,也置为0

    75. 颜色分类

    给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

    此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

    public class Solution {
        public void sortColors(int[] nums) {
            int i = -1, j = -1, k = -1;
            for (int m = 0; m < nums.length; m++) {
                if (nums[m] == 0) {
                    nums[++k] = 2;
                    nums[++j] = 1;
                    nums[++i] = 0;
                } else if (nums[m] == 1) {
                    nums[++k] = 2;
                    nums[++j] = 1;
                } else {
                    nums[++k] = 2;
                }
            }
        }
    }

    78、子集

    public class Solution {
        List<List<Integer>> lists = new ArrayList<List<Integer>>();
        public List<List<Integer>> subsets(int[] nums) {
    
            Arrays.sort(nums);
            for (int i = 0; i <=nums.length; i++) {
                backTracking(new ArrayList<Integer>(), nums, 0, i);
            }
    
            return lists;
        }
    
        private void backTracking(ArrayList<Integer> cur, int[] nums,
                int from, int target) {
            // TODO Auto-generated method stub
            if (cur.size() == target) {
                List<Integer> list = new ArrayList<Integer>(cur);
                lists.add(list);
            } else {
                for (int i = from; i < nums.length; i++) {
                    cur.add(nums[i]);
                    backTracking(cur, nums, i + 1, target);
                    cur.remove(new Integer(nums[i]));
                }
            }
        }
    }

    英文:https://leetcode.com/problemset/all/

    中文:https://leetcode-cn.com/

  • 相关阅读:
    053-005
    053-002
    053-004
    Dynamic Programming: Fibonacci
    Some tips on using HashSet<T> and List<T>
    使用NPOI导出DataTable到Excel
    简简单单写个特效
    vue项目使用tinymce 适用于5.0版本
    封装AJAX
    全屏滑动效果
  • 原文地址:https://www.cnblogs.com/tilamisu007/p/9726321.html
Copyright © 2011-2022 走看看