2019.7.22~2019.7.28 刷题总结

1. 三数之和

题目描述:
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。

解题思路:
先将数组排序,依次选择第一个数A,然后在其后面的数里面选择满足条件的数,设置两个指针,一个L指向头部B,一个R指向尾部C,当A,B,C之和小于0,则L++,当A,B,C之和大于0,则R++,当A,B,C等于0,则加入返回结果中,需要注意的是,答案中不可以包含重复的三元组,因此,当A,B,C等于0时,需要判断L指针的后一个数是否与当前数相等,以及R指针的前一个数是否与当前数相等,如果相等,则指针加一。

代码:

public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for(int i = 0;i<nums.length;i++)
        {
            if(nums[i] > 0)
            {
                break;
            }
            if(i>0 && nums[i] == nums[i-1])
            {
                continue;
            }
            int L = i+1;
            int R = nums.length-1;
            while(L<R)
            {  
                int sum = nums[i] +nums[L] +nums[R];
                if(sum ==0 )
                {
                    List<Integer> list = new ArrayList<>();
                    list.add(nums[i]);
                    list.add(nums[L]);
                    list.add(nums[R]);
                    res.add(list);
                     while(L<R && nums[L] == nums[L+1])
                {
                    L++;
                }
                while(L<R && nums[R] == nums[R-1])
                {
                    R--;
                }
                    R--;
                    L++;
                }else if (sum < 0)
                {
                    L++;
                }else{
                    R--;
                }      
            }      
        }
        return res;
    }

2. 移动0

题目描述:
给定一个数组 nums,编写一个函数将所有 0移动到数组的末尾,同时保持非零元素的相对顺序。

解题思路:
设置两个指针,一个i指向当前位置,一个j指向数组从头开始非0的位置,当i指向的数不等于0,则令j指向的数等于i指向的数,并且i和j都移动一位,如果i指向的数等于0,则i移动一位。

代码:

public void moveZeroes(int[] nums) {
        int i = 0;
        int j = 0;
        while(i<nums.length)
        {
            if(nums[i] == 0)
            {
                i++;
            }else{
                nums[j++] = nums[i++];
            }
        }
        while(j<i)
        {
            nums[j++] = 0;
        }
    }
}

3. 按奇偶排序数组

题目描述:
给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数。
对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数。

解题思路:
设置两个奇偶数组,一个存放奇数,一个存放偶数,然后将数组中的奇偶数分别放进这两个数组中,最后将奇偶数组中的数按原数组的下标,还原到原数组中。

代码:

class Solution {
    public int[] sortArrayByParityII(int[] A) {
        int [] odd = new int [A.length/2];
        int [] even = new int [A.length/2];
        int m = 0;
        int n = 0;
        for(int i = 0;i< A.length;i++)
        {
            if(A[i] % 2 ==0)
            {
                even[m++] = A[i];
            }else{
                odd[n++] = A[i];
            }
        }
        m = 0;
        n = 0;
        for(int j = 0;j< A.length;j++)
        {
            if(j % 2 == 0)
            {
                A[j] = even[m++];
            }else{
                A[j] = odd[n++];
            }
        }
        return A;
    }
}

4.字符串的排列

题目描述:
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

代码:

public ArrayList<String> Permutation(String str) {
       ArrayList<String> arr = new ArrayList<>();
        fun(str.toCharArray(), 0, arr);
        Collections.sort(arr);
        return arr;
        
    }
    
    public void fun(char[]chr,int i, ArrayList<String> array)
    {
        if(i == chr.length -1)
        {
            String str = new String(chr);
            if(!array.contains(str))
            {
                array.add(str);
            }
        }else{
            for(int j = i;j< chr.length;j++)
            {
                swap(chr,i,j);
                fun(chr, i+1, array);
                swap(chr, i, j);
            }
        }
    }
    public void swap(char []chr, int i, int j)
    {
        char temp = chr[i];
        chr[i] = chr[j];
        chr[j] = temp;
    }

5.数组中出现次数超过一半的数字

题目描述:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

代码:

public int MoreThanHalfNum_Solution(int [] array) {
        if(array.length == 0)
        {
            return 0;
        }
        if(array.length == 1)
        {
            return array[0];
        }
        int [] bocket= new int [array.length];
        for(int i = 0;i<array.length;i++)
        {
            bocket[array[i]]++;
        }
        for(int j = 0;j<bocket.length;j++)
        {
            if(bocket[j] > array.length/2)
            {
                return j;
            }
        }
        return 0;
    }

6.数字在排序数组中出现的次数

题目描述:
统计一个数字在排序数组中出现的次数。

代码:

public int GetNumberOfK(int [] array , int k) {
        if(array == null ||array.length == 0 || k < array[0] || k> array[array.length -1])
        {
            return 0;
        }
       return find(array, k, 0 ,array.length -1);
    }
    
    public int find(int [] array, int k, int begin, int end)
    {
         if(begin >= end)
        {
            if(array[begin] == k)
            {
                return 1;
            }else{
                return 0;
            }
        }
        int count = 0;
        int mid = begin + (end - begin) /2;
        if(array[mid] < k)
        {
            return find(array, k, begin, mid-1);
        }
        else if (array[mid] == k)
        {
            count++;
            int left =  mid-1;
            while(left >= 0 && array[left] == k)
            {
                count++;
                left--;
            }
            int right = mid+1;
            while(right <= array.length -1 && array[right] == k)
            {
                count++;
                right++;
            }
            return count;
        }else{
            return find(array, k ,mid+1, end);
        }
    }

7.二叉树的深度

题目描述:
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

代码:

 public int TreeDepth(TreeNode root) {
        if(root == null)
        {
            return 0;
        }public class Solution {
     private boolean isBlance = true;
    public boolean IsBalanced_Solution(TreeNode root) {
        getDepth(root);
        return isBlance;
    }
    
    public  int getDepth(TreeNode root)
    {
        if(root == null)
        {
            return 0;
        }
        int left = getDepth(root.left);
        int right = getDepth(root.right);
        if(Math.abs(left-right) > 1)
        {
            isBlance = false;
            
        }
        return left > right ? left+1:right+1;
    }
}
        int left = TreeDepth(root.left);
        int right = TreeDepth(root.right);
        return left > right ? left+1:right +1;
    }

8.平衡二叉树

题目描述:
输入一棵二叉树,判断该二叉树是否是平衡二叉树

代码:

public class Solution {
     private boolean isBlance = true;
    public boolean IsBalanced_Solution(TreeNode root) {
        getDepth(root);
        return isBlance;
    }
    
    public  int getDepth(TreeNode root)
    {
        if(root == null)
        {
            return 0;
        }
        int left = getDepth(root.left);
        int right = getDepth(root.right);
        if(Math.abs(left-right) > 1)
        {
            isBlance = false;
            
        }
        return left > right ? left+1:right+1;
    }
}

9.和为S的连续正数序列

题目描述:
小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100。但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? Good Luck!

代码:

 public ArrayList<ArrayList<Integer> > FindContinuousSequence(int sum) {
        ArrayList<ArrayList<Integer> > arr = new ArrayList<ArrayList<Integer> >();
        if(sum<1)
        {
            return arr;
        }
       int left = 1;
        int right = 2;
        int total =3;
        while(left < right && right < sum)
        {
            if(total < sum)
            {
                right++;
                total += right;
            }else if(total == sum)
            {
                ArrayList<Integer> temp = new ArrayList<Integer>();
                   
                for(int i = left;i<=right;i++)
                {
                    temp.add(i);
                }
                arr.add(temp);
                total = total - left;
                left++;
                
            }else{
                total -=left;
                left++;
                 
            }
        }
        return arr;
    }

10.和为S的两个数字

题目描述:
输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

代码:

public ArrayList<Integer> FindNumbersWithSum(int [] array,int sum) {
        ArrayList<Integer> arrayList = new ArrayList<>();
        int left = 0;
        int right = array.length -1;
        
      
        while(left < right)
        {
           int  S = array[left] + array[right];
            if(sum == S)
            {
                arrayList.add(array[left]);
                arrayList.add(array[right]);
                break;
                
               
            }else if(sum >S)
            {
               
                left ++;
                
            }else {
                
                right--;
            }
        }
     
        return arrayList;
        
    }

11. 左旋转字符串

题目描述:
汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

代码:

public String LeftRotateString(String str,int n) {
        if(str == null || str.equals(""))
        {
            return "";
        }
        if(str.length() < n)
        {
            n = n% str.length();
        }
        String temp = str + str;
        return temp.substring(n,str.length()+ n);
    }

12.翻转单词顺序列

题目描述:
牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

代码:

public String ReverseSentence(String str) {
        if(str.trim().equals("") || str== null)
        {
            return str;
        }
        String [] arr = str.split(" ");
        
        for(int i = 0;i<arr.length/2;i++)
        {
            swap(arr, i, arr.length-i-1);
        }
        String res= arr[0];
        for(int j = 1;j< arr.length;j++)
        {
            res+=" "+ arr[j];
        }
        return res;
    }
    
    public static void swap(String [] arr, int i, int j)
    {
         String temp = arr[i];
        arr[i] = arr[j];
        arr[j]  = temp;
    }

13.求1+2+3+…n

题目描述:
求1+2+3+…+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

代码:

public int Sum_Solution(int n) {
       int sum = (int)(Math.pow(n,2) + n);
        return sum>>1;
    }

14.把字符串转换成整数

题目描述:
将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。

代码:

public int StrToInt(String str) {
        if(str.trim().equals(""))
        {
            return 0;
        }
        int res = 0;
        boolean type = true;
        int i = 0;
        if(str.charAt(0) == '-')
        {
            type = false;
            i = 1;
        }
        else if(str.charAt(0) == '+')
        {
            i=1;
        }
        for(;i<str.length();i++)
        {
            char temp = str.charAt(i);
            if(str.charAt(i) >= '0' && str.charAt(i) <= '9')
            {
                res += (temp - '0') * Math.pow(10,str.length() - 1- i);
            }else{
                return 0;
            }
        }
        if(!type && res >= 2147483647 && str.charAt(str.length()-1) == '8')
        {
            return -1*res-1;
        }
        return type ? res : (-1 * res);
    }

15.数组中重复的数字

题目描述:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

代码:

public boolean duplicate(int numbers[],int length,int [] duplication) {
        if(numbers==null || length<1) return false;
        for(int i =0 ;i<length;i++){
            while(numbers[i]!= i){
                if(numbers[i] == numbers[numbers[i]]){
                    duplication[0] = numbers[i];
                    return true;
                }
                swap(numbers,i,numbers[i]);
            }
        }
        return false;
    }
    public void swap(int[] arr ,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

16.表示数值的字符串

题目描述:
请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。

代码:

 public boolean isNumeric(char[] str) {
        boolean hasE = false;
        boolean hasDot = false;
        
        for(int i = 0;i<str.length;i++)
        {
            if(str[i] == 'e' || str[i] == 'E')
            {
                if(i == str.length -1)
                {
                    return false;
                }
                
                if(hasE)
            {
                return false;
               
            }
            else{
                hasE = true;
            }
            }else if (str[i] == '.')
            {
                if(hasE)
                {
                    return false;
                }
                if(hasDot)
                {
                    return false;
                }else{
                    hasDot = true;
                }
            }else if (str[i] == '-' || str[i] == '+')
            {
                if(i > 0 && str[i-1] != 'e' && str[i-1] != 'E')
                {
                    return false;
                }
                if(i<str.length-1 && (str[i+1] == '-' || str[i+1] == '+'))
                {
                    return false;
}
            }else if(str[i] <'0' || str[i] > '9')
            {
                return false;
            }
            
        }
        return true;
    }

17.不用加减乘除做加法

题目描述:
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

代码:

public int Add(int num1,int num2) {
        while(num2!=0)
        {
            int temp = num1 ^ num2;
            num2 = (num1 & num2) <<1;
            num1 = temp;
        }
        return num1;
    }

18.第一个只出现一次的字符

题目描述:
在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写).

代码:

public static int FirstNotRepeatingChar(String str) {
        int[] count = new int[52];
        int[] index = new int[52];
        for (int i = 0; i < str.length(); i++) {
            char temp = str.charAt(i);
            if (temp >= 'a' && temp <= 'z') {
                int a = str.charAt(i) - 'a' + 26;
                
                count[a]++;
                index[a] = i;
            } else {
                int b = str.charAt(i) - 'A';
                
                count[b]++;
                index[b] = i;
            }
        }
        int temp = str.length();
        boolean sign = false;
        for (int j = 0; j < 52; j++) {
            if (count[j] == 1) {
                sign = true;
                if (index[j] < temp) { public int GetUglyNumber_Solution(int index) {
        if(index < 7)
        {
            return index;
        }
       
        int []ret = new int [index];
         ret[0] =1;
        int t2=0,t3=0,t5=0;
        for(int i = 1;i< index;i++)
        {
            ret[i] = min(min(ret[t2]*2, ret[t3]*3), ret[t5]*5);
            if(ret[i] == ret[t2]*2)
            {
                t2++;
            }
            if(ret[i] == ret[t3]*3)
            {
                t3++;
}
            if(ret[i] == ret[t5] * 5)
            {
                t5++;
}
        }
        return ret[index-1];
    }
    
    public static int min(int a, int b)
    {
        return a>b ? b:a;
}
                    temp = index[j];
                }
            }
        }
        return sign ? temp : -1;
    }

19.丑数

题目描述:
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数

代码:

 public int GetUglyNumber_Solution(int index) {
        if(index < 7)
        {
            return index;
        }
       
        int []ret = new int [index];
         ret[0] =1;
        int t2=0,t3=0,t5=0;
        for(int i = 1;i< index;i++)
        {
            ret[i] = min(min(ret[t2]*2, ret[t3]*3), ret[t5]*5);
            if(ret[i] == ret[t2]*2)
            {
                t2++;
            }
            if(ret[i] == ret[t3]*3)
            {
                t3++;
}
            if(ret[i] == ret[t5] * 5)
            {
                t5++;
}
        }
        return ret[index-1];
    }
    
    public static int min(int a, int b)
    {
        return a>b ? b:a;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值