剑指offer第二版和专项突击版有啥区别
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer第二版和专项突击版有啥区别相关的知识,希望对你有一定的参考价值。
参考技术A 剑指offer第二版和专项突击版区别在于内容和重点不同:1、内容上《剑指offer第二版》内部的题目顺序是按照从易到难的顺序排列,便于初学者逐步提升。
2、《剑指offer专项突击版》的内容上则把题目分成了10个章节,分别涵盖了数组、链表、栈和队列、字符串、树、图、算法思想、位运算、数学问题和多线程与并发等算法类型。
3、《剑指offer第二版》在对所有题目进行讲解时,都会详细地介绍题目的背景、算法思路和代码实现等内容,讲解比较全面。
4、《剑指offer专项突击版》则更加注重突出每种算法的核心思想和特点,给读者更深刻的印象。
Leetcode训练剑指 Offer(专项突击)——双指针全刷
目录
- [剑指 Offer II 006. 排序数组中两个数字之和](https://leetcode-cn.com/problems/kLl5u1/)——简单
- [剑指 Offer II 007. 数组中和为 0 的三个数](https://leetcode-cn.com/problems/1fGaJU/)——中等
- [剑指 Offer II 014. 字符串中的变位词](https://leetcode-cn.com/problems/MPnaiL/)——中等
- [剑指 Offer II 018. 有效的回文](https://leetcode-cn.com/problems/XltzEq/)——简单
- [剑指 Offer II 019. 最多删除一个字符得到回文](https://leetcode-cn.com/problems/RQku0D/)——简单
- [剑指 Offer II 021. 删除链表的倒数第 n 个结点](https://leetcode-cn.com/problems/SLwz0R/)——中等
- [剑指 Offer II 022. 链表中环的入口节点](https://leetcode-cn.com/problems/c32eOV/)——中等
- [剑指 Offer II 023. 两个链表的第一个重合节点](https://leetcode-cn.com/problems/3u1WK4/)——简单
- [剑指 Offer II 026. 重排链表](https://leetcode-cn.com/problems/LGjMqU/)——中等
- [剑指 Offer II 027. 回文链表](https://leetcode-cn.com/problems/aMhZSa/)——简单
- [剑指 Offer II 056. 二叉搜索树中两个节点之和](https://leetcode-cn.com/problems/opLdQZ/)——简单
- [剑指 Offer II 077. 链表排序](https://leetcode-cn.com/problems/7WHec2/)——中等
分享Leetcode——剑指Offer专项突击版——双指针刷题
https://leetcode-cn.com/problem-list/e8X3pBZi/
剑指 Offer II 006. 排序数组中两个数字之和——简单
题目描述:
题解
方法一:数组已经排序了,直接首尾双指针;
class Solution
public int[] twoSum(int[] numbers, int target)
int arr[] = new int[2];
int i = 0;
int j = numbers.length-1;
while(i<=j)
if (numbers[i]+numbers[j]>target)
j--;
else if (numbers[i]+numbers[j]<target)
i++;
else
arr[0]=i;
arr[1]=j;
break;
return arr;
剑指 Offer II 007. 数组中和为 0 的三个数——中等
题目描述
题解:
方法一:暴力破解(超时)
题解链接:https://leetcode-cn.com/problems/1fGaJU/solution/jian-dan-yi-dong-javac-pythonjs-san-shu-nu6el/
class Solution
public List<List<Integer>> threeSum(int[] nums)
if (nums==null||nums.length<3)
return new ArrayList<>();
Set<List<Integer>> res = new HashSet<>();
Arrays.sort(nums); // 时间复杂度 O(nlogn)
// Set<List<Integer>> set = new HashSet<>();
// O(n^3)
for (int i = 0; i < nums.length; i++)
for (int j = i+1; j < nums.length; j++)
for (int k = j+1; k < nums.length; k++)
if (nums[i]+nums[j]+nums[k]==0)
// List<Integer> temp = Arrays.asList(nums[i],nums[j],nums[k]);
// Collections.sort(temp); // 对list排序
res.add(Arrays.asList(nums[i],nums[j],nums[k]));
return new ArrayList<>(res);
方法二:双指针
题解链接:https://leetcode-cn.com/problems/1fGaJU/solution/jian-dan-yi-dong-javac-pythonjs-san-shu-nu6el/
class Solution
public List<List<Integer>> threeSum(int[] nums)
if (nums==null||nums.length<3)
return new ArrayList<>();
List<List<Integer>> res= new ArrayList<>();
Arrays.sort(nums); // 时间复杂度 O(nlogn)
//时间复杂度 O(n^2)
for (int i = 0; i < nums.length-2; i++) // 时间复杂度O(n)
// i 去重
if (i>0 && nums[i]==nums[i-1])
continue;
// 在 i + 1 ... nums.length - 1 中查找相加等于 -nums[i] 的两个数
int target = -nums[i];
int left = i+1;
int right = nums.length-1;
while (left<right) // 时间复杂度O(n)
int sum = nums[left]+nums[right];
if (sum==target)
res.add(Arrays.asList(nums[i],nums[left],nums[right]));
// 去重 如果前一个left==后面的left 跳过
// while (left<right&& nums[left]==nums[++left]);
// while (left<right&& nums[right]==nums[--right]);
while (left<right)
left++;
if (nums[left-1]!=nums[left])
break; // 当left-1 !=left 的时候 跳出left++循环 左指针去重完毕
while (left<right)
right--;
if (nums[right]!=nums[right+1])
break; // 当 right != right+1的时候 跳出right--循环 右指针去重完毕
else if (sum < target)
left++;
else
right--;
return res; // O(n)
剑指 Offer II 014. 字符串中的变位词——中等
题目描述
题解
class Solution
public boolean checkInclusion(String s1, String s2)
int m = s1.length();
int n = s2.length();
if (m>n)
return false;
int cnt1[] = new int[26];
for (char c:s1.toCharArray())
cnt1[c - 'a']++;
int left = 0;
int cnt2[] = new int[26];
for(int right =0;right < n;right++)
int idx = s2.charAt(right) - 'a';
cnt2[idx]++;
while (cnt2[idx]>cnt1[idx])
cnt2[s2.charAt(left)-'a']--;
left++;
if (right-left+1==m)
return true;
return false;
优化
class Solution
public boolean checkInclusion(String s1, String s2)
int n = s1.length();
int m = s2.length();
int cnt[] = new int[26];
for(int i=0;i<n;i++)
cnt[s1.charAt(i)-'a']--;
int left = 0;
for(int right=0;right<m;right++)
int in = s2.charAt(right)-'a';
cnt[in]++;
while(cnt[in]>0)
cnt[s2.charAt(left)-'a']--;
left++;
if (right-left+1==n)
return true;
return false;
复杂度分析
剑指 Offer II 018. 有效的回文——简单
题目描述
题解
方法一:无脑判断思维reverse()
class Solution
public boolean isPalindrome(String s)
StringBuffer sb = new StringBuffer();
s = s.toLowerCase();
for (int i = 0; i < s.length(); i++)
char c = s.charAt(i);
if (Character.isLetterOrDigit(c))
sb.append(c);
return sb.toString().equals(new StringBuffer(sb).reverse().toString());
方法二:双指针
class Solution
public boolean isPalindrome(String s)
int left = 0;
int right = s.length() - 1;
s = s.toLowerCase();
char c1;
char c2;
while (left < right)
if (!Character.isLetterOrDigit(s.charAt(left)))
left += 1;
else if (!Character.isLetterOrDigit(s.charAt(right)))
right -=1;
else
c1 = s.charAt(left);
left++;
c2 = s.charAt(right);
right--;
if (c1 != c2)
return false;
return true;
剑指 Offer II 019. 最多删除一个字符得到回文——简单
题目描述:
题解
class Solution
public boolean validPalindrome(String s)
StringBuffer sb = new StringBuffer();
int left = 0;
int right = s.length()-1;
while (left<right)
// 如果不相等,则分两种情况:删除左边的元素,或者右边的元素,再判断各自是否回文,满足一种即可。
if (s.charAt(left)!=s.charAt(right))
return isPalindrome(s, left+1, right)||isPalindrome(s, left, right-1);
left++;
right--;
return true;
// 判断字符串 s 的 [left, right] 是否回文
public boolean isPalindrome(String s, int left,int right)
while (left<right)
if (s.charAt(left)!=s.charAt(right))
return false;
left++;
right--;
return true;
复杂度分析
剑指 Offer II 021. 删除链表的倒数第 n 个结点——中等
题目描述
给定一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
题解
/**
* Definition for singly-linked list.
* public class ListNode
* int val;
* ListNode next;
* ListNode()
* ListNode(int val) this.val = val;
* ListNode(int val, ListNode next) this.val = val; this.next = next;
*
*/
class Solution
public ListNode removeNthFromEnd(ListNode head, int n)
// 创建辅助头节点,head , fast 和 slow 都指向这个辅助头节点
ListNode fast = new ListNode(0);
fast.next = head;
head = fast;
ListNode slow = fast;
// fast 指针先走 n + 1 个单位
for(int i = 0; i <= n; i++)
fast = fast.next;
// fast 指针和 slow 指针一起移动,直到 fast 指向空后,slow 指针则指向倒数第 n + 1个节点。
while (fast != null)
slow = slow.next;
fast = fast.next;
// 删除倒数第 n 个节点
slow.next = slow.next.next;
// 由于我们设置了辅助头节点,所以 head.next 才是链表的首元节点。
return head.next;
复杂度分析
剑指 Offer II 022. 链表中环的入口节点——中等
题目描述
示例 1:
示例 2:
示例 3:
题解
方法一:哈希表
一个非常直观的思路是:我们遍历链表中的每个节点,并将它记录下来;一旦遇到了此前遍历过的节点,就可以判定链表中存在环。借助哈希表可以很方便地实现。
public class Solution
public ListNode detectCycle(ListNode head)
ListNode pos = head;
Set<ListNode> set = new HashSet<>();
while (pos !=null)
if (set.contains(pos))
return pos;
else
set.add(pos);
pos = pos.next;
return pos;
复杂度分析
方法二:快慢指针
-
假设快慢指针相遇时,慢指针slow走了k步,那么快指针fast一定走了2k步
-
Leetcode训练剑指 Offer(专项突击)——双指针全刷