题目一:

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

分析:这道题目是一个链表题,对链表元素相加得出一个新的链表,那么怎么能实现链表元素的相加呢?其实这和我们实现两个数相加很类似,首先应该从个位数开始,如果之和大于10则将向前进一位。

1、创建一个新的链表,用于返回最后相加和的结果,ListNode DummyNode=new ListNode(0);

2、设置一些指向链表的节点,分别指向l1,l2,DummyNode, p1=l1,p2=l2,curr=DummyNode;

3、开始遍历列表,进行求和,首先获取了l1,l2头节点的值,在进行相加  int x=(p1!=null)? p1.val:0;    int y=(p2!=null)? p2.val:0;   int sum=x+y+count;

4、这里的难点在于求和后的结果超过10应该怎么办?我们应该将其记录下来,然后添加到下一次求和中,如上式的sum,记录的方式为:sum=sum/10,结果是0或者1;

5、curr节点应该添加一个新的节点,并且存放所求得的和值,方式为curr.next=new ListCode(sum%10);

6、将curr,p1,p2分别向后移动指针, curr=curr.next;    if(p1!=null) p1=p1.next;    if(p2!=null) p2=p2.next;

7、如果在最后一轮循环中count大于1,这需要新创建一个节点  curr.next=new ListNode(count);

8、返回链表DummyNode.next,因为第一个节点为0,无意义。

具体实现过程:

class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { ListNode DummyNode=new ListNode(0);
ListNode p1=l1,p2=l2,curr=DummyNode; int count=0;
while(p1!=null||p2!=null)
{
int x=(p1!=null)? p1.val:0;
int y=(p2!=null)? p2.val:0;
int sum=x+y+count;
count=sum/10; curr.next=new ListNode(sum%10);
curr=curr.next;
if(p1!=null) p1=p1.next;
if(p2!=null) p2=p2.next;
} if(count>0)
curr.next=new ListNode(count); return DummyNode.next;
}
}

题目二:

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

方法一:暴力法

1、获得字符串长度,用二次循环直接遍历所有的可能性 for(int i=0; i<s.lenght;i++) for(int j=i+1;j<s.lenght;j++)

2、获取所有字符串长度的最大值,ans=Math.max(ans,j-i)

3、这里最主要的一部是获取字符串长度的比较,首先设置一个集合Set<Character> set=new HashSet<>();

4、将字符串s,i,j的位置传入判断函数,获取传入的值Character ch=s.CharAt(i),获取索引i的值;

5、判断ch值是否重复,if(set.contain(ch)) return false,set.add(ch);

6、返回true;

具体代码:

class Solution {
public int lengthOfLongestSubstring(String s) { int n=s.length();
int ans=0; for(int i=0;i<n;i++)
for(int j=i+1;j<=n;j++)
{
if(JugleFun(s,i,j)) ans=Math.max(ans, j-i);
} return ans;
} public boolean JugleFun(String s,int start,int end)
{
Set<Character> set=new HashSet<>(); for(int i=start;i<end;i++)
{
Character ch=s.charAt(i);
if(set.contains(ch)) return false;
set.add(ch);
} return true;
}
}

方法二:滑动窗口

1、使用i=0,j=0两个值向后逐个滑动;

2、主要的思想:如果遍历过字符串为不重复子串,就没必要再去重复判断,如果1234561,i=1,j=1,直接从i=2和j=1进行判断;

3、if(!set.contain(s.charAt(j))),set.add(s.char(j++))  否则set.remove(s.charAt(i++));

具体代码:

class Solution {
public int lengthOfLongestSubstring(String s) { int n=s.length();
int i=0,j=0,ans=0;
Set<Character> set=new HashSet<>(); while(i<n&&j<n)
{
if(!set.contains(s.charAt(j)))
{
set.add(s.charAt(j++));
ans=Math.max(ans, j-i);
}
else {
set.remove(s.charAt(i++));
}
} return ans;
}
}

题目三:

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"
输出: true

分析:

1、字符的两两匹配问题,先将其放入哈希表中,HashMap<Character,Character> hashmap=new HashMap<>();

2、在构造函数中进行初始化,hashmap.put(')','(');

3、应该使用栈数据结构,将放入的元素和栈顶元素对比,Stack<Character> stack=new Stack<>(),获取串元素:k=s.CharAt(i);

4、如果是哈希表中的键,将进行对比,否则直接压栈,if(hashmap.containKey(c)), 获取栈顶元素:Character topElem=stack.empty()? '#':stack.pop();

5、比较栈顶元素和要入栈的元素是否相同,if(topElem!=hashmap.get(c))

6、返回栈是否为空,return stack.empty();

具体代码:

class Solution {

    private HashMap<Character, Character> hashMap=new HashMap<Character,Character>();

    public Solution()
{
hashMap.put(')', '(');
hashMap.put('}', '{');
hashMap.put(']', '[');
} public boolean isValid(String s) { Stack<Character> stack=new Stack<>(); for(int i=0;i<s.length();i++)
{
char c=s.charAt(i); if(hashMap.containsKey(c))
{
Character topEle=stack.empty()? '#':stack.pop(); if(topEle!=hashMap.get(c))
return false;
} else {
stack.push(c);
}
}
return stack.empty();
}
}

题目四:

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

方法一:

1、删除倒数第n个节点,先应该遍历出链表的长度,然后用lenght=length-n;

2、判断链表长度定位到删除的位置,if(lenght>0) curr=curr.next;

3、需要设置两个节点,一个用来遍历curr,另一个指向头结点,ListNode dummy=new ListNode;

4、返回dummy.next;

具体代码:

class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) { ListNode curr=head;
ListNode dummy=new ListNode(0);
dummy.next=head;
int count=0; while(curr!=null)
{
count++;
curr=curr.next;
}
count-=n;
curr=dummy;
while(count>0)
{
count--;
curr=curr.next;
}
curr.next=curr.next.next;
return dummy.next;
}
}

方法二:

分析:

1、采用双指针实现,first指针先执行n步,然后second指针开始执行;

2、直到first为空,停止执行second;

3、将second指针指向下一个节点second.next=second.next.next;

4、开始设置哑结点指向头结点,first和second都指向dummy;

具体代码:

class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) { ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode first=dummy;
ListNode second=dummy; for(int i=1;i<=n+1;i++)
{
first=first.next;
} while(first!=null)
{
first=first.next;
second=second.next;
} second.next=second.next.next; return dummy.next;
}
}

题目五:

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

方法一:暴力法

判断字符串中的回文,并将最大的回文串返回

1、将所有的字符串进行遍历,判断每个字符串是否为回文;

2、可以另外设置一个函数进行判断,判断字符串的第一位和最后一位是否相同即可,即if(s.charAt(i)==s.charAt(lenght-i-1))

3、设置返回的字符串为ans=" ";如果字符串为回文,那么返回最大的字符串,ma=0;if(str.lengt>0),ans=str,ma=Math.max(max,str.lenght);

4、返回length;

class Solution {
public String longestPalindrome(String s) { String ans="";
int ma=0; for(int i=0;i<s.length();i++)
for(int j=i+1;j<=s.length();j++)
{
String str=s.substring(i,j);
if(isHuiWei(str)&&str.length()>ma)
{
ans=s.substring(i,j);
ma=Math.max(ma, ans.length());
}
}
return ans;
} public boolean isHuiWei(String s)
{ int len=s.length();
for(int i=0;i<len/2;i++)
{
if(s.charAt(i)!=s.charAt(len-i-1))
{
return false;
}
}
return true;
} }

方法二:动态规划

class Solution {
public String longestPalindrome(String s) { int len=s.length();
if(len<=1)
return s; int longpa=1;
String string=s.substring(0,1);
boolean[][] dp=new boolean[len][len]; for(int r=1;r<len;r++)
for(int l=0;l<r;l++)
{
if(s.charAt(l)==s.charAt(r)&&(r-l<=2||dp[l+1][r-1]))
{
dp[l][r]=true;
if(r-l+1>longpa)
{
longpa=r-l+1;
string=s.substring(l,r+1);
}
}
}
return string;
}
}

题目六:

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

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

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

方法一:

1、递归算法,递归出口:if(m==1||n==1) return 1;

2、返回结果:ans=uniquePath(m-1,n)+uniquePath(m,n-1);

具体代码:

class Solution {
public int uniquePaths(int m, int n) { if(m==||n==)
return ; int ans=uniquePaths(m-, n)+uniquePaths(m, n-); return ans;
}
}

方法二:

1、动态规划,状态方程:dp[i][j]=dp[i-1][j]+dp[i][j-1];

2、状态初始化:dp[i][0]=1,dp[0][j]=1;

3、返回最后的结果,return dp[m-1][n-1];

具体代码:

class Solution {
public int uniquePaths(int m, int n) { int[][] dp=new int[m][n]; for(int i=;i<=m;i++) dp[i][]=;
for(int i=;i<=n;i++) dp[][i]=;
for(int i=;i<=m;i++)
for(int j=;j<=m;j++)
{
dp[i][j]=dp[i-][j]+dp[i][j-];
}
return dp[m-][n-];
}
}

题目七:

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

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

说明:

所有数字(包括 target)都是正整数。
解集不能包含重复的组合。 
示例 1:

输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]

方法:

回溯加递归

具体代码:

class Solution {

    private int[] candidates;
private List<List<Integer>> res=new ArrayList<>();
private int len; public List<List<Integer>> combinationSum(int[] candidates, int target) { int len=candidates.length;
if(len==0)
return res; Arrays.sort(candidates);
this.len=len;
this.candidates=candidates; findCombinationSum(target,0,new Stack<>());
return res;
} public void findCombinationSum(int target,int start,Stack<Integer> stack)
{
if(target==0)
{
res.add(new ArrayList<>(stack));
return;
} for(int i=start;i<len&&(target-candidates[i])>=0;i++)
{
stack.add(candidates[i]);
findCombinationSum(target-candidates[i], i, stack);
stack.pop();
}
}
}

题目八:

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

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

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

示例 1:

输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。

方法一:

1、递归算法,我们想要实现是否满足路径;

2、创建一个函数实现是个可以从一个位置,从位置0开始,是否能够到达最后一个位置;

3、实现递归,第二个位置是否能够实现到达最后一个位置; 将所有的可能性都列举出来,位置1可能到达的位置;

4、fasterPos=Math.min(positon+nums[position]),进行循环fasterPos次;

具体代码:

class Solution {
public boolean canJump(int[] nums) { return FromCanJump(0, nums);
} public boolean FromCanJump(int position,int[] nums)
{
int len=nums.length-1;
if(position==len)
return true; int FasterDistance=Math.min(position+nums[position], len);
for(int nextPostion=position+1;nextPostion<=FasterDistance;nextPostion++)
{
if(FromCanJump(nextPostion, nums))
return true;
} return false;
}
}

方法二:

将递归出来的元素保存在一个数组中

具体代码:

enum Index
{GOOD,BAD,UNKOWN} class Solution {
Index[] mono; public boolean canJump(int[] nums) {
mono=new Index[nums.length]; for(int i=0;i<mono.length;i++)
{
mono[i]=Index.UNKOWN;
}
mono[mono.length-1]=Index.GOOD; return canJumpPosition(0,nums);
} public boolean canJumpPosition(int position, int[] nums)
{
if(mono[position]!=Index.UNKOWN)
{
return mono[position]==Index.GOOD?true:false;
} int furthestJump = Math.min(position + nums[position], nums.length - 1);
for (int nextPosition = position + 1; nextPosition <= furthestJump; nextPosition++) {
if (canJumpPosition(nextPosition, nums)) {
mono[position] = Index.GOOD;
return true;
}
} mono[position] = Index.BAD;
return false;
}
}

题目九:

给定一个二叉树,返回其按层次遍历的节点值。 (即逐层地,从左到右访问所有节点)。

例如:
给定二叉树: [3,9,20,null,null,15,7],

3
/ \
9 20
/ \
15 7

方法一:

1、递归,二叉树层次遍历用递归可以实现;

2、不过需要做一些简单的设置,并不能原函数上进行递归,原函数只给定了根节点;

3、还需要另外一个参数,层level,对这个函数进行递归;

4、if(levels.size()==level) 增加一个数组,levels.add(new Arraylist());

5、添加元素到数组中,levels.get(level).add(node.val);

具体代码:

class Solution {

    List<List<Integer>> levels=new ArrayList<>();

    public List<List<Integer>> levelOrder(TreeNode root) {

        if(root==null) return levels;
Creatlevel(root, 0); return levels;
} public List<List<Integer>> Creatlevel(TreeNode node,int level)
{
if(levels.size()==level)
levels.add(new ArrayList<>()); levels.get(level).add(node.val); if(node.left!=null)
Creatlevel(node.left, level+1);
if(node.right!=null)
Creatlevel(node.right, level+1); return levels;
}
}

方法二:

队列

具体代码:

class Solution {

    public List<List<Integer>> levelOrder(TreeNode root) {

        List<List<Integer>> levels=new ArrayList<>();
if(root==null) return levels; Queue<TreeNode> queue=new LinkedList<TreeNode>();
queue.add(root); int level=0;
while(!queue.isEmpty())
{
levels.add(new ArrayList<>());
int level_size=levels.size(); for(int i=0;i<level_size;i++)
{
TreeNode node=queue.remove();
levels.get(level).add(node.val); if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right); }
level++;
}
}
}

题目十:

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

示例 1:

输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL

方法:

1、链表的移动,遍历整个链表,先找到尾节点的值,并把尾结点指向head使得链表构成一个环;

2、for(int n=1;old_tail!=null;n++) old_tail=old_tail.next,这里需要记录一下整个链表的长度;

3、定义一个新的尾结点new_tail,for(int i=0;i<n-k%n-1;i++) new_tail=new_tail.next,这里的循环条件满足k>n;

4、定义一个新的头节点new_head=new_tail.next;new_tail.next=null;

5、返回new_head;

具体代码:

class Solution {
public ListNode rotateRight(ListNode head, int k) { if(head==null) return null;
if(head.next==null) return head; ListNode old_tail=head;
int n;
for(n=1;old_tail.next!=null;n++)
{
old_tail=old_tail.next;
}
old_tail.next=head; ListNode new_tail=head;
for(int i=0;i<n-k%n-1;i++)
{
new_tail=new_tail.next;
} ListNode new_head=new_tail.next;
new_tail.next=null; return new_head;
}
}

LeetCode中等题(一)的更多相关文章

  1. leetcode 中等题(2)

    50. Pow(x, n) (中等) double myPow(double x, int n) { ; unsigned long long p; ) { p = -n; x = / x; } el ...

  2. leetcode 中等题(1)

    2. Add Two Numbers(中等) /** * Definition for singly-linked list. * struct ListNode { * int val; * Lis ...

  3. LeetCode中等题(三)

    题目一: 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明:1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, m ...

  4. leetcode中等题

    # Title Solution Acceptance Difficulty Frequency     1 Two Sum       44.5% Easy     2 Add Two Number ...

  5. LeetCode中等题(二)

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

  6. 这样leetcode简单题都更完了

    这样leetcode简单题都更完了,作为水题王的我开始要更新leetcode中等题和难题了,有些挖了很久的坑也将在在这个阶段一一揭晓,接下来的算法性更强,我就要开始分专题更新题目,而不是再以我的A题顺 ...

  7. LeetCode刷题笔记和想法(C++)

    主要用于记录在LeetCode刷题的过程中学习到的一些思想和自己的想法,希望通过leetcode提升自己的编程素养 :p 高效leetcode刷题小诀窍(这只是目前对我自己而言的小方法,之后会根据自己 ...

  8. leetcode刷题指南

    转载自:http://blog.csdn.net/lnho2015/article/details/50962989 以下是我个人做题过程中的一些体会: 1. LeetCode的题库越来越大,截止到目 ...

  9. LeetCode刷题总结-数组篇(上)

    数组是算法中最常用的一种数据结构,也是面试中最常考的考点.在LeetCode题库中,标记为数组类型的习题到目前为止,已累计到了202题.然而,这202道习题并不是每道题只标记为数组一个考点,大部分习题 ...

随机推荐

  1. Git 安装配置及工作流程

    在使用Git前我们需要先安装 Git.Git 目前支持 Linux/Unix.Solaris.Mac和 Windows 平台上运行. Git 各平台安装包下载地址为:http://git-scm.co ...

  2. PyQt5程序基本结构分析

    面向过程版 # 0. 导入需要的包和模块 from PyQt5.Qt import * # 包含了我们常用的QT中的一些类 import sys # 一个内置的模块,系统相关操作 # 代码执行的时候, ...

  3. 吴裕雄 python 神经网络——TensorFlow训练神经网络:全模型

    import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data INPUT_NODE = 784 ...

  4. IEEE 802.11r-2008

    IEEE 802.11r-2008 or fast BSS transition (FT), also called fast roaming, is an amendment to the IEEE ...

  5. node vue 项目git 管理

    push 上传到云的时候,依赖包及相关文件是不上传上去的, 所以每次克隆到本地后,node 项目运行前须要 npm install 安装对应依赖 vue 项目编译前也须要  npm install,安 ...

  6. mybatis源码探索笔记-3(使用代理mapper执行方法)

    前言 前面两章我们构建了SqlSessionFactory,并通过SqlSessionFactory创建了我们需要的SqlSession,并通过这个SqlSession获取了我们需要的代理mapper ...

  7. Nginx实现HTTP及TCP负载均衡

    这种通过一台apache的服务器把客户请求分别传递给两台tomcat叫负载均衡  ========================================= ================= ...

  8. shell脚本部署apache并能通过浏览器访问!

    第一步:导入httpd-2.2.17.tar包 第二步:创建一个test.sh文件(可在/root下) 第三步编写shell脚本 > 会重写文件,如果文件里面有内容会覆盖 >>这个是 ...

  9. [运维] 如何在云服务器上安装 MySQL 数据库, 并使用 Navicat 实现远程连接管理

    .•●•✿.。.:*.•●•✿.。.:*.•●•✿.。.:*.•●•✿.。.:*.•●•✿.。.:*.•●•✿.。.:*.•.•●•✿.。.:*.•●•✿.。.:*.•●•✿.。.:*.•●•✿.。. ...

  10. 同一条sql insert 有时快有时慢 引发的血案

    同一条sql语句,为什么有时插入块,有时插入慢原因剖析 背景:同一条sql ,有时插入时间几毫秒,有时插入时间几十毫秒,为什么? Sql角度:简单insert 表角度: 一个主键 系统参数角度: 开启 ...