(1)给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?示例 1:
输入: [2,2,1]
输出: 1
示例 2:输入: [4,1,2,1,2]
输出: 4
解法一:位运算
class Solution {
public int singleNumber(int[] nums) {
int result=0;
for(int num:nums){
result^=num;
}
return result;
}
}
解法二:哈希表
/*Map的基本操作——put、get、containsKey、containsValue、size以及isEmpty*/
//使用map
public int findOnly(int [] nums){
Map<Integer,Integer> map=new HashMap<>();
for(Integer i:nums){
map.put(i,map.containsKey(i)? map.get(i)+1:1);
}
for (Map.Entry<Integer, Integer> en: map.entrySet()) {
int key = en.getKey();
int value = en.getValue();
if (value==1) return key;
}
return -1;
}
(2)多数元素
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:[3,2,3]
输出:3
示例 2:
输入:[2,2,1,1,1,2,2]
输出:2
public int majorityElement(int[] nums) {
Map<Integer,Integer> map=new HashMap<>();
for(int i:nums){
map.put(i,map.containsKey(i)?map.get(i)+1:1);
}
int resultkey=-1;
int resultvalue=0;
for(Map.Entry<Integer,Integer> en:map.entrySet()){
int key=en.getKey();
int value=en.getValue();
if(value>resultvalue){
resultkey=key;
resultvalue=value;
}
}
return resultkey;
}
(3)统计「优美子数组」 题目描述 给你一个整数数组 nums 和一个整数 k。 如果某个连续子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。 请返回这个数组中「优美子数组」的数目。 示例 1: 输入:nums = [1,1,2,1,1], k = 3 输出:2 解释:包含 3 个奇数的子数组是 [1,1,2,1] 和 [1,2,1,1] 。 示例 2: 输入:nums = [2,4,6], k = 1 输出:0 解释:数列中不包含任何奇数,所以不存在优美子数组。 示例 3: 输入:nums = [2,2,2,1,2,2,1,2,2,2], k = 2 输出:16 数据范围
@Test
public void test2(){
int []nums={2,2,2,1,2,2,1,2,2,2};
int k=2;
int result=firstarray(nums,k);
System.out.println(result);
}
public int firstarray(int []nums,int k){
int result=0;
for(int i=0;i<nums.length-k;i++){
int count=0;
for(int j=i;count<=k && j<nums.length;j++){
if(nums[j]%2==1) count++;
if(count==k){
result++;
}
}
}
return result;
}
面试题 01.01. 判定字符是否唯一 * 实现一个算法,确定一个字符串 s 的所有字符是否全都不同。 示例 1: 输入: s = "leetcode" 输出: false 示例 2: 输入: s = "abc" 输出: true
#Map解法
public boolean isUnique(String astr) {
char [] chars=astr.toCharArray();
Map<Character,Integer> map=new HashMap<>();
for(char ch: chars){
map.put(ch,map.containsKey(ch)?map.get(ch)+1:1);
if (map.get(ch)>=2) return false;
}
return true;
}
#Set解法
#利用 Set 不可重复性
public boolean isUnique(String astr) {
Set<Character> set = new HashSet<>();
for (int i = 0; i < astr.length(); i++) {
set.add(astr.charAt(i));
}
return set.size() == astr.length();
}
面试题 01.02. 判定是否互为字符重排 给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。 示例 1: 输入: s1 = "abc", s2 = "bca" 输出: true 示例 2: 输入: s1 = "abc", s2 = "bad" 输出: false
/*此方法遇到s1=aab,s2=abb时解答错误*/
public boolean CheckPermutation(String s1, String s2) {
char []chars=s1.toCharArray();
if(s1.length()!=s2.length()) return false;
for(char ch:chars){
if(s2.indexOf(ch)==-1) return false;
}
return true;
}
//正确解法
public boolean CheckPermutation2(String s1, String s2) {
if(s1.length()!=s2.length()) return false;
char []chars1=s1.toCharArray();
Arrays.sort(chars1);
char []chars2=s2.toCharArray();
Arrays.sort(chars2);
for(int i=0;i<chars1.length;i++){
if(chars1[i]!=chars2[i]) return false;
}
return true;
}
最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
/*暴力求解
暴力求解是最容易想到的,要截取字符串的所有子串,然后再判断这些子串中哪些是回文的,最后返回回文子串中最长的即可。
这里我们可以使用两个变量,一个记录最长回文子串开始的位置,一个记录最长回文子串的长度,最后再截取。代码如下*/
@Test
public void testlongestPalindrome(){
String s="babad";
String result=longestPalindrome(s);
System.out.println(result);
}
public String longestPalindrome(String s) {
if(s.length()<2) return s;
int start=0;
int maxLen=0;
for(int i=0;i<s.length()-1;i++){
for(int j=i;j<s.length();j++){
if(maxLen>j-i+1) continue;;
if(Palindrome(s,i,j)){
if(maxLen<j-i+1){
start=i;
maxLen=j-i+1;
}
}
}
}
return s.substring(start,start+maxLen);
}
public boolean Palindrome(String s,int start,int end){
while (start<end){
if(s.charAt(start)!=s.charAt(end)) return false;
start++;
end--;
}
return true;
}
穿插一个小知识点:解决斐波那契数列中递归的重复计算
/* 递归改进:那么避免重复计算的方法就是,每计算得到一个值,便用一个数组保存这个值,下次计算该值的时候直接引用就可以了。*/
public int fibonacci(int n) {
int[] array = new int[n + 1];
if (n < 2) {return 0;}
if (2 == n) {return 1;}
array[1] = 0;
array[2] = 1;
return helper(array, n);
}
private int helper(int[] array, int n) {
if (n < 2) {
return 0;
}
if (2 == n) {
return 1;
}
array[n] = helper(array, n - 1) + array[n - 2]; // 保存每次计算的结果
return array[n];
}
动态规划算法题:
/*爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
*/
@Test
public void testclimbStairs(){
int result=climbStairs(5);
System.out.println(result);
}
public int climbStairs(int n) {
if(n==1) return 1;
if(n==2) return 2;
int []num=new int[n+1];
num[1]=1;
num[2]=2;
for(int i=3;i<=n;i++){
num[i]=num[i-1]+num[i-2];
}
return num[n];
}
/*最大子数组和:给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。
示例 1:
输入:nums = [-2,1,-3,4,-1,2,1,-5,4]
输出:6
解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:
输入:nums = [1]
输出:1
示例 3:
输入:nums = [5,4,-1,7,8]
输出:23
*/
@Test
public void testmaxSubArray(){
int []nums = {-2,1,-3,4,-1,2,1,-5,4};
int result=maxSubArray(nums);
System.out.println(result);
}
public int maxSubArray(int[] nums) {
int len=nums.length;
//dip[i]表示:以num[i]结尾的连续子数组的最大和
int [] dp=new int[len];
for(int i=1;i<len;i++){
if(dp[i-1]>0){
dp[i]=dp[i-1]+nums[i];
}else {
dp[i]=nums[i];
}
}
//求最大值
int res=dp[0];
for(int i=1;i<len;i++){
res=Math.max(res,dp[i]);
}
return res;
}
/*最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"
输出:"bb"
*/
public String longestPalindrome(String s) {
if (s.length() < 2)
return s;
int start = 0;
int maxLen = 0;
for (int i = 0; i < s.length() - 1; i++) {
for (int j = i; j < s.length(); j++) {
//截取所有子串,如果截取的子串小于等于之前
//遍历过的最大回文串,直接跳过。因为截取
//的子串即使是回文串也不可能是最大的,所以
//不需要判断
if (j - i < maxLen)
continue;
if (isPalindrome(s, i, j)) {
if (maxLen < j - i + 1) {
start = i;
maxLen = j - i + 1;
}
}
}
}
return s.substring(start, start + maxLen);
}
//判断是否是回文串
private boolean isPalindrome(String s, int start, int end) {
while (start < end) {
if (s.charAt(start++) != s.charAt(end--))
return false;
}
return true;
}