LeetCode简单题(二)
题目一:
给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。
方法一:
1、这是一个数组的就地删除操作,通过双指针可以将其实现;
2、设置一个快指针,一个慢指针,循环遍历一个变量是实现不了的;
3、慢指针i=0;快指针遍历数组,如果是删除的值,直接跳过,否则将元素复制到慢指针数组中,慢指针加1;
4、这里最有趣的是如果数组元素和比较元素不相等,直接跳过;
具体代码:
class Solution {
public int removeElement(int[] nums, int val) {
int j=0;
for(int i=0;i<nums.length;i++)
{
if(nums[i]!=val)
{
nums[j]=nums[i];
j++;
}
}
return j;
}
}
方法二:
1、如果数组的值和value值相同,将最后一个元素赋给这个值;
2、n--将数组最后一个值删除;
具体代码:
class Solution {
public int removeElement(int[] nums, int val) {
int i=0;
int n=nums.length;
while(i<n)
{
if(nums[i]==val)
{
nums[i]=nums[n-1];
n--;
}
else {
i++;
}
}
return n;
}
}
题目二:
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
方法一:
1、主要使用哈希表,将值进行存储起来;
2、for(i:nums) Integer count=map.get(i);count=count==1?1:++count;
3、进行搜索,for(i:map.keySet())
具体代码:
class Solution {
public int singleNumber(int[] nums) {
Map<Integer, Integer> map=new HashMap<>();
for(int i:nums)
{
Integer count=map.get(i);
count=(count==null)?1:++count;
map.put(i, count);
}
for(int i:map.keySet())
{
Integer count=map.get(i);
if(count==1)
return i;
}
return -1;
}
}
方法二:
1、异或操作,主要是异或操作的两个性质;
2、两个相同的数进行以后操作结果为0;0和一个数进行异或操作结果依旧为这个数;
3、以后操作有点强;
具体代码:
class Solution {
public int singleNumber(int[] nums) {
int result=0;
for(int i=0;i<nums.length;i++)
{
result=result^nums[i];
}
return result;
}
}
题目三:
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
方法一:
1、暴力法,也就是通过递归实现;
2、总方法=先上一个楼梯到n个楼梯+先上2个楼梯到n个楼梯;
3、递归出口:如果i==n,return 1; 如果i>n return 0;
具体代码:
class Solution {
public int climbStairs(int n)
{
return climb_stairs(0, n);
}
public int climb_stairs(int i,int n)
{
if(i>n)
return 0;
if(i==n)
return 1;
return climb_stairs(i+1, n)+climb_stairs(i+2, n);
}
}
方法二:
1、问题的最优解可以通过子问题的最优解得出,使用动态规划;
2、状态方程:到第i楼梯的解法=到第i-1楼梯解法+到第i-2楼梯解法-------dp[i]=dp[i-1]+dp[i-2];
3、返回dp[n];
具体代码:
public class Solution {
public int climbStairs(int n) {
if(n==1)
return 1;
int[] dp=new int[n+1];
dp[1]=1;
dp[2]=2;
for(int i=3;i<=n;i++)
{
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}
}
方法三:
1、使用斐波那契数列,有趣的是dp[i]=dp[i-1]+dp[i-2]刚好是斐波那契数列;
2、可以省去空间对一些值的存储;
具体代码:
public class Solution {
public int climbStairs(int n) {
if(n==1)
return 1;
int first=1;
int second=2;
for(int i=3;i<=n;i++)
{
int third=first+second;
first=second;
second=third;
}
return second;
}
}
题目四:
给定两个二进制字符串,返回他们的和(用二进制表示)。
输入为非空字符串且只包含数字 1 和 0。
示例 1:
输入: a = "11", b = "1"
输出: "100"
方法:
1、二进制求和,其实和10进制求和类似,先从最后一位开始,有2进1;
2、因为返回的是字符串,而中间需要获取单个字符,返回的数据类型为StringBuilder;
3、具体的计算过程:定义ca=0;sum+=i>=0?a.charAt(i)-'0':0; 对字符串类似进行相加;
4、得到最后一位:ans.append(sum%2);
5、获取进位ca=sum/2;
6、最后判断是否有进位ca,ans.append(ca==0? 1:" ");
7、将字符串进行反转转化为String类型;
最后说明使用StringBuilder和StringBuffer的区别,其实这两个类功能基本相同,只不过StringBuffer是线程安全,StringBuilder线程不安全但单线程相对较快;
具体代码:
class Solution {
public String addBinary(String a, String b) {
StringBuilder anStringBuilder=new StringBuilder();
int ca=0;
for(int i=a.length()-1,j=b.length()-1;i>=0||j>=0;i--,j--)
{
int sum=ca;
sum+=i>=0?a.charAt(i)-'0':0;
sum+=j>=0?b.charAt(j)-'0':0;
anStringBuilder.append(sum%2);
ca=sum/2;
}
anStringBuilder.append(ca==1? ca:"");
return anStringBuilder.reverse().toString();
}
}
题目五:
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
方法一:
1、通过迭代方式,逐步实现;
2、核心思想是设置当前指针curr,需要一个临时节点保存当前节点指向的下一个节点,将curr.next指向前一个元素;
3、再将curr节点赋值到pre节点,临时节点temp赋值到curr节点,继续向后遍历;
4、返回pre节点就是解;
具体代码;
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre=null;
ListNode curr=head;
while(curr!=null)
{
ListNode temp=curr.next;
curr.next=pre;
pre=curr;
curr=temp;
}
return pre;
}
}
方法二:
1、通过递归实现,递归出口:if(head==null||head.next==null) return head
2、求reserveList(head.next);
3、head.next.next=head;head.next=null;思考递归一定要整体考虑,可以求得不包括head的其他节点的反链表;
4、再通过指针的指向实现和头节点的链接;
具体代码:
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null)
return head;
ListNode pListNode=reverseList(head.next);
head.next.next=head;
head=null;
return pListNode;
}
}
题目六:
给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。
如果不存在最后一个单词,请返回 0 。
说明:一个单词是指由字母组成,但不包含任何空格的字符串。
示例:
输入: "Hello World"
输出: 5
方法:
1、逆向思维,从字符串的最后开始遍历,遇到空格停止遍历,将其距离输出;
2、如果刚开始最后的字符为空格,应该先把这些空格去掉,end=s.lenght();while(end>=0&&s,charAt(end)==' ') end--;
3、接着取最后一位到第一个空格后的距离:int start=end,while(start>=0&&s.charAt(start)!=' ') start--;
4、返回end-start;
具体代码:
class Solution {
public int lengthOfLastWord(String s) {
int end=s.length()-1;
while(end>=0&&s.charAt(end)==' ') end--;
int start=end;
while(start>=0&&s.charAt(start)!=' ') start--;
return end-start;
}
}
题目七:
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
方法一:
1、递归法;
2、求出根节点左节点的最大深度和右节点的最大深度进行比较求最大值,然后再加1;
具体代码:
public int maxDepth(TreeNode root) {
int result=0;
if(root==null)
return 0;
else {
int left_height=maxDepth(root.left);
int right_height=maxDepth(root.right);
result=Math.max(left_height, right_height)+1;
}
return result;
}
题目八:
public class Main{
public static int main(String[] args)
{
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int[] w=new int[n];
for(int i=0;i<n;i++)
{
w[i]=input.nextInt();
}
int m=input.nextInt();
int[] h=new int[m];
for(int i=0;i<m;i++)
{
h[i]=input.nextInt();
}
Arrays.sort(w);
Arrays.sort(h);
int count=0;
int stu=0;
for(int i;i<n;i++)
{
if(w[i]>h[stu])
continue;
else {
count++;
stu++;
if(stu==n)
break;
}
}
System.out.println(count);
}
}
题目九:
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
方法:
使用双指针和临时变量进行,再用一个while循环。
具体代码:
class Solution {
public void reverseString(char[] s) {
int i=0,j=s.length-1;
while(i<j)
{
char temp=s[j];
s[j]=s[i];
s[i]=temp;
i++;
j--;
}
}
}
题目十:
给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在众数。
示例 1:
输入: [3,2,3]
输出: 3
方法一:
1、使用双重循环,第一层遍历所有元素,第二层将所有元素进行计数;
2、如果计数值count超过了len/2,则将其返回,否则返回-1;
3、这里面使用foreach语句使得代码更加简单直观,并且每次计数从从0开始。
具体代码:
class Solution {
public int majorityElement(int[] nums) {
int len=nums.length/2;
for(int num:nums)
{
int count=0;
for(int elem:nums)
{
if(elem==num)
count++;
}
if(count>len)
return num;
}
return -1;
}
}
方法二:
1、采用哈希表法,先将所有的元素和计数存储在一个哈希表中;
2、Map<Integer,Integer> map=new HashMap<>(),for(num:nums) if(!map.containKey(num)) map.put(num,1)
3、否则,map.put(num,map.get(num)+1),这一步相当关键;
4、首先通过数组获取到哈希表count;
5、定义要返回的最大值,Map.Entry<Integer,Integer> Mentry=null;
6、遍历哈希表for(Map.Entry<Integer,Integer> entry:couny.entrySet());
7、if(Mentry==null||entry.getValue()>Mentry.GetValue()) Mentry=entry;
8、返回Metry.getKey();
9、值得注意的是,这里用Map.Entry是因为获取键值都可以直接获取;
具体代码:
class Solution {
private Map<Integer, Integer> countGere(int[] nums)
{
Map<Integer, Integer> counts=new HashMap<>();
for(int num:nums)
{
if(!counts.containsKey(num))
{
counts.put(num, 1);
}
else {
counts.put(num, counts.get(num)+1);
}
}
return counts;
}
public int majorityElement(int[] nums) {
Map<Integer,Integer> counts=countGere(nums);
Map.Entry<Integer, Integer> majorEntry=null;
for(Map.Entry<Integer, Integer> entry:counts.entrySet())
{
if(majorEntry==null||entry.getValue()>majorEntry.getValue())
{
majorEntry=entry;
}
}
return majorEntry.getKey();
}
}
方法三:
1、排序,因为这里的众数是大于一般以上的数;
2、所有将排序后的数组中,最中间的数返回一定就是众数;
具体代码:
class Solution {
public int majorityElement(int[] nums)
{
Arrays.sort(nums);
return nums[nums.length/2];
}
}
LeetCode简单题(二)的更多相关文章
- 这样leetcode简单题都更完了
这样leetcode简单题都更完了,作为水题王的我开始要更新leetcode中等题和难题了,有些挖了很久的坑也将在在这个阶段一一揭晓,接下来的算法性更强,我就要开始分专题更新题目,而不是再以我的A题顺 ...
- leetcode简单题6
今天的华师 Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, fro ...
- C#LeetCode刷题-二叉搜索树
二叉搜索树篇 # 题名 刷题 通过率 难度 220 存在重复元素 III 19.3% 中等 315 计算右侧小于当前元素的个数 31.9% 困难 327 区间和的个数 29.5% 困难 3 ...
- Go: LeetCode简单题,简单做(sort.Search)
前言 正值端午佳节,LeetCode也很懂.这两天都是简单题,早点做完去包粽子. 故事从一道简单题说起 第一个错误的版本 简单题 你是产品经理,目前正在带领一个团队开发新的产品.不幸的是,你的产品的最 ...
- LeetCode简单题(三)
题目一: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股 ...
- LeetCode中等题(二)
题目一: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复 ...
- LeetCode简单题(一)
题目一: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组 ...
- LeetCode简单题(四)
题目一: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你 ...
- LeetCode简单题汇总
1.两个数之和 给出一个整数数组,请在数组中找出两个加起来等于目标值的数, 你给出的函数twoSum 需要返回这两个数字的下标(index1,index2),需要满足 index1 小于index ...
随机推荐
- MYSQL内置函数【转】
一.MySQL 字符串函数 函数 描述 实例 ASCII(s) 返回字符串 s 的第一个字符的 ASCII 码. 返回 CustomerName 字段第一个字母的 ASCII 码: SELECT AS ...
- dbGet(三)
inst flat design下的instance Parent Object group, hInst, instTerm, io, pBlkg, ptn, rBlkg, sdp, topCell ...
- 开源协议:LGPL协议、OSGi协议
本文介绍开源的协议. LGPL 是 GNU Lesser General Public License (GNU 宽通用公共许可证)的缩写形式,旧称 GNU Library General Publi ...
- SpringBoot启动后自动打开浏览器访问项目
之前我们用SSM或者SSH进行JAVA WEB开发的时候,IDEA 需要配置Tomcat然后把项目放到tomcat运行,tomcat启动的时候会自动打开浏览器去访问项目,但是SpringBoot是内嵌 ...
- js 判断对象的属性是否存在
1.in运算符 (属性名 in 对象) 情况1:对象自身属性 var obj={a:1}; "a" in obj//true 情况2:对象继承的属性 var objA={a:1} ...
- 【MySQL】外键的变种
" 目录 三种关系 多对一 多对多 一对一 因为有foreign key的约束,使得两张表形成了三种关系: 多对一 多对多 一对多 重点理解如何找出两张表之间的关系 现在有A.B两张表 分析 ...
- js函数声明外面使用小括号括起来再接一个小括号的写法
js函数声明外面使用小括号括起来再接一个小括号的写法 (function(){})(); (function(){}()); !function(){}(); 总结ps:意思将函数声明变成,直接执行的 ...
- python requests.request 和session.request区别究竟在哪里
import requests hd={"X-auth":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzeXN0ZW0iLCJBUEkiOiIvdW ...
- 一个HTTP数据包的奇幻之旅
我是一个HTTP数据包,不知谁创建了我,把我丢到这个房间. 突然,来了一个大汉,我吓得缩到角落. “该启程了,站起来”. “去哪里啊?” 我弱弱的问. “还能去哪里,你是一个数据包,当然要出远门,完成 ...
- 第三方控件引起的"类型Universe无法解析程序集"的血案
前一阵子在项目中添加了IrisSkin2皮肤控件,今天用VS打开悲剧了. 提示"类型Universe无法解析程序集:System.Design,Version=2.0.0.0,Culture ...