leetcode刷题指北(2)

9.回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
思路一:
第一反应转为字符串,遍历字符串首尾是否相等。

class Solution {
    public boolean isPalindrome(int x) {
    String s=x+"";
    for (int i = 0; i < s.length() - 1; i++) {
			if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
				return false;
			}
		}
		return true;
    }
}

也可以使用字符串反转比较

class Solution {
    public boolean isPalindrome(int x) {
    String s=x+"";
		StringBuffer rs= new StringBuffer(s);
		if(s.equals(rs.reverse().toString())) {
			return true;
		}else{
            return false;
        }
    }
}

思路二:
反转一半数字

class Solution {
    public boolean isPalindrome(int x) {
        if(x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }
        int revertedNumber = 0;
        while(x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }
        return x == revertedNumber || x == revertedNumber/10;
    }
}

寻找数组的中心索引
输入:
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释:
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。
思路一:
以分割点下标对数组进行迭代,分别计算两端数组和。

class Solution {
    public int pivotIndex(int[] nums) {
       int len = nums.length;
       int i=0;
	   for(;i<len;i++) {
		   int suml=0;
		   for(int j=0;j<i;j++) {
			   suml+=nums[j];
		   }
		   int sumr=0;
		   for(int j=i+1;j<len;j++)
			   sumr+=nums[j];
		   if(suml==sumr)
               return i;
	   }
        return -1;
    }
}

至少是其他数字两倍的最大数
在一个给定的数组nums中,总是存在一个最大元素 。
查找数组中的最大元素是否至少是数组中每个其他数字的两倍。
如果是,则返回最大元素的索引,否则返回-1。
输入: nums = [3, 6, 1, 0]
输出: 1
解释: 6是最大的整数, 对于数组中的其他整数,
6大于数组中其他元素的两倍。6的索引是1, 所以我们返回1.
思路一:
找最大数和次大数

class Solution {
    public int dominantIndex(int[] nums) {
       int len = nums.length;
	   int max=0;
	   int last=0;
	   int index=0;
	   for(int i=0;i<len;i++) {
		   if(nums[i]>max) {
			   last=max;
			   max=nums[i];
			   index=i;
		   }
           else if(nums[i]>last)
			   last=nums[i];
	   }
	   if(max>=2*last) {
		   return index;
	   }else {
		   return -1;
	   }
    }
}

加一
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
思路一:
从最后一位按位迭代,如果为9则迭代进位。

class Solution {
    public int[] plusOne(int[] digits) {
		int len=digits.length;
        for(int i=len-1;i>=0;i--) {
			if(digits[i]!=9) {
				digits[i]+=1;
				return digits;
			}else {
				digits[i]=0;
			}
		}
        int [] res=new int[len+1];
        res[0]=1;

        return res;
        
    }
}

杨辉三角
输入: 5
输出:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]
思路一:
从第3行开始,除首尾元素外,每个元素是上行依次两个元素的和。

class Solution {
    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res = new ArrayList<>();
		List<Integer> pre=new ArrayList<>();
        if(numRows==0)
            return res;
		pre.add(1);
		res.add(pre);
		for(int i=1;i<numRows;i++) {
			List<Integer> tmp=new ArrayList<>();
			tmp.add(1);
			for(int j=0;j<pre.size()-1;j++) {
				tmp.add(pre.get(j)+pre.get(j+1));
			}
			tmp.add(1);
			pre=tmp;
			res.add(pre);
		}
        return res;
    }
}

二进制求和
示例 1:
输入: a = “11”, b = “1”
输出: “100”
思路一:二进制加法规律,两个数求和再对2取余,结果为本位最终值,如果进位则对和除以2得到1至高位求和。
从最低位计算,结果存StringBuffer中,最后反转即得到最终结果。

class Solution {
    public String addBinary(String a, String b) {
        StringBuffer res= new StringBuffer();
		int lena=a.length()-1;
		int lenb=b.length()-1;
		int sum = 0;
		while(lena>=0||lenb>=0) {
			int tmp=sum;
			if(lena>=0) {
				tmp+=(a.charAt(lena)-'0');
				lena--;
			}
			if(lenb>=0) {
				tmp+=(b.charAt(lenb)-'0');
				lenb--;
			}
			res.append(tmp%2);
			sum=tmp/2;		
		}
		if(sum!=0)
			res.append(1);
		String re=res.reverse().toString();
        return re;
    }
}

实现strStr()
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = “hello”, needle = “ll”
输出: 2
思路一:迭代,设置flag跳出。

class Solution {
    public int strStr(String haystack, String needle) {
        if(needle.equals(""))
            return 0;
        char [] cha=haystack.toCharArray();
		char [] chb=needle.toCharArray();
        int res=-1;
        for(int i =0;i<=cha.length-chb.length;i++) {
			boolean flag=true;
			for(int j=0;j<chb.length;j++) {
				if(cha[i+j]!=chb[j]) {
					flag=false;
					break;
				}				
			}
			if(flag==true)
                return i;
		}
        return res;
    }
}

最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “”。
示例 1:
输入: [“flower”,“flow”,“flight”]
输出: “fl”
思路一:
先找到数组中最短元素,最长公共子串不会超过最短元素
对第一个元素迭代分割,分割后的子串用于迭代比较是否相同。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        String res="";
        if(strs==null||strs.length==0){
            return res;
        }
        if(strs.length==1){
            return strs[0];
        }
		int min = strs[0].length();
		for(int i=1;i<strs.length;i++) {
			if(min>strs[i].length())
				min=strs[i].length();
		}
		int i=1;
		boolean flag = true;
		for (i = 1; i <= min; i++) {			
			String tmp = strs[0].substring(0, i);
			for (int j = 0; j < strs.length; j++) {
				if (!tmp.equals(strs[j].substring(0, i))) {
					flag = false;
					break;
				}
			}		
			if (flag == false) {
				if(i==1) {
                    return "";
				}else {
                    return strs[0].substring(0, i - 1);
				}
			}
			if (flag == true && i==min) {
                return strs[0].substring(0, i);
			}
		}
        return res;
    }
}

反转字符串
编写一个函数,其作用是将输入的字符串反转过来。
示例 1:
输入: “hello”
输出: “olleh”
思路一:双向指针
转成字符数组,首尾两指针向里迭代。

扫描二维码关注公众号,回复: 5013072 查看本文章
class Solution {
    public String reverseString(String s) {   
        char[] chars=s.toCharArray();
        int begin=0;
        int end=chars.length-1;
        while(begin<end) {
			char tmp = chars[begin];
			chars[begin]=chars[end];
			chars[end]=tmp;
			begin++;
			end--;
		}
        return new String(chars);
    }
}

思路二:利用StrinBuilder

class Solution {
    public String reverseString(String s) {
        String res="";
		StringBuilder strs= new StringBuilder(s);
		strs.reverse();
		res=strs.toString();
        return res;
    }
}

拓展:
句子中单词反转。
例如:
输入:“student. a am I”
输出:“I am a student.”
思路一:反转两次

public class Solution {
    public String ReverseSentence(String str) {
        if(str.length()==0||str.trim().length()==0)
            return str;
        char[] chars = str.toCharArray();
        int mark=0;
        for(int i=0;i<chars.length;i++) {
            if(chars[i]==' ') {
                swapStr(chars,mark,i-1);
                mark=i+1;
            }
        }
        swapStr(chars,mark,chars.length-1);
        swapStr(chars,0,chars.length-1);
        return new String(chars);
    }
    public static void swapStr(char[] chars,int begin,int end) {
        while(begin<end) {
            char tmp = chars[begin];
            chars[begin]=chars[end];
            chars[end]=tmp;
            begin++;
            end--;
        }
    }
}

思路二:StringBuilder数据结构

public class Solution {
    public String ReverseSentence(String str) {
        if(str.length()==0||str.trim().length()==0)
            return str;
        String [] strs=str.split(" ");
        StringBuffer sb= new StringBuffer();
        for(int i=strs.length-1;i>=0;i--){
            sb.append(strs[i]);
            if(i>0)
                sb.append(" ");
        }
        return sb.toString();
    }
}

数组拆分 I
给定长度为 2n 的数组, 你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从1 到 n 的 min(ai, bi) 总和最大。
示例 1:
输入: [1,4,3,2]
输出: 4
解释: n 等于 2, 最大总和为 4 = min(1, 2) + min(3, 4).
思路一:排序后只对偶数求和。

class Solution {
    public int arrayPairSum(int[] nums) {
        Arrays.sort(nums);
		int sum=nums[0];
		for(int i=2;i<nums.length;i+=2) {
			sum+=nums[i];
		}
        return sum;
    }  
}

两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
示例:输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
思路一:二分法

class Solution {
    public int[] twoSum(int[] numbers, int target) {
        int[] res = new int [2];
		for(int i=0;i<numbers.length;i++) {
			int t=target-numbers[i];
			int begin=i+1;
			int end=numbers.length-1;
			while(begin<=end) {
				int mid=(begin+end)/2;
				if(t==numbers[mid]) {
                    res[0]=i+1;
                    res[1]=mid+1;
					 return res;
				}
				else if(t>numbers[mid]) {
					begin=mid+1;
				}
				else if(t<numbers[mid])
					end=mid-1;						
			}
		}
        return res;     
    }
}

移除元素
给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2
你不需要考虑数组中超出新长度后面的元素。

思路:快慢指针

class Solution {
    public int removeElement(int[] nums, int val) {
        int k=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]!=val){
                nums[k++]=nums[i];
            }
        }
        return k;
    }
}

最大连续1的个数
给定一个二进制数组, 计算其中最大连续1的个数。
示例 1:
输入: [1,1,0,1,1,1]
输出: 3
解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3.
思路一:
两层迭代

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int count = 0;
		int left = 0;
		for (int i = 0; i < nums.length; i++) {
			int tmp=0;
			for (int j = i; j < nums.length; j++) {
				if (nums[j] == 1) {
					tmp++;
				} else if(nums[j] ==0)
					break;
			}
			if(tmp>count) {
				count=tmp;
			}
		}
        return count;
    }
}

思路二:
一次迭代,如果为1则加一,为0存储最大值,计数为0重新计数。

class Solution {
    public int findMaxConsecutiveOnes(int[] nums) {
        int count=0;
		int max=0;
		for(int i=0;i<nums.length;i++) {
			if(nums[i]==1)
				count++;
			else {
				max=Math.max(count, max);
				count=0;
			}
		}
        return Math.max(count, max);
    }
}

猜你喜欢

转载自blog.csdn.net/sky_noodle/article/details/82692513