From 58d54114baee5cd65b80cc50f8ebb67edb36af28 Mon Sep 17 00:00:00 2001 From: no5ix <1145263208@qq.com> Date: Mon, 2 Dec 2024 19:14:24 -0700 Subject: [PATCH] update algo_na: lc347 Quick Select related problem --- source/_posts/algo_na.md | 297 ++++- source/_posts/algo_newbie.md | 3 +- .../eng_life_youtube_interview_politics_1.md | 21 +- source/_posts/eng_talk_show.md | 12 + source/code/test_algo_na.java | 1180 ++++++++++------- 5 files changed, 998 insertions(+), 515 deletions(-) create mode 100644 source/_posts/eng_talk_show.md diff --git a/source/_posts/algo_na.md b/source/_posts/algo_na.md index ba9665935f..d37e77b7c1 100644 --- a/source/_posts/algo_na.md +++ b/source/_posts/algo_na.md @@ -88,6 +88,65 @@ public class test{ } ``` +### 二分查找扩展题 - lc69 - 求平方 + +- https://leetcode.com/problems/sqrtx/description/ + +``` java +class Solution { + public int mySqrt(int x) { + if (x == 0 || x == 1) { + return x; + } + int left = 1; + int right = x; + int mid = 0; + while (left <= right) { + mid = left + (right - left) / 2; + if ((long)mid * mid > x) { + right = mid - 1; + } else if ((long)mid * mid < x) { + left = mid + 1; + } else { + return mid; + } + } + // 为什么返回right而不是left? 因为最后是left 大于了right才退出循环的, 所以要取小的那个, 退出循环的时候right小一些 + // 比如 [1, 2, 3, 4, 5, 6, 7, 8], 最后一轮循环是 left=3, right=3, 然后此时mid也等于3, 3*3=9 所以 right得减一, right 就等于2 了 + return right; + } +} +``` + +## lc27 + +- https://programmercarl.com/0027.移除元素.html#算法公开课 +- https://leetcode.com/problems/remove-element/description/ + +双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。 + +定义快慢指针: +- 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组 +- 慢指针:指向更新 新数组下标的位置 + +诀窍: 应该想象成 slowIndex 之前的那些数组格子就是新的数组 + +``` java +class Solution { + public int removeElement(int[] nums, int val) { + int slowIndex = 0; + int fastIndex = 0; + for (;fastIndex < nums.length; fastIndex++) { + if (nums[fastIndex] != val) { + nums[slowIndex++] = nums[fastIndex]; + } + } + return slowIndex; + } +} +``` + + ## lc977 - 有序数组的平方 - 20240916 - https://programmercarl.com/0977.有序数组的平方.html#算法公开课 @@ -126,10 +185,90 @@ public class test{ } ``` +# 链表 + +## lc206 - 链表反转 + +- https://programmercarl.com/0206.翻转链表.html#算法公开课 +- https://leetcode.com/problems/reverse-linked-list/description/ + +- 重要!!!!! 记忆口诀: 举一反(反转)三(3个指针! pre! cur! temp!) +- 核心要点就是需要保存一个后面可能要用的结点就弄一个指针出来, 比如这个pre + +``` java +// 双指针 +class Solution { + public ListNode reverseList(ListNode head) { + ListNode prev = null; + ListNode cur = head; + ListNode temp = null; + while (cur != null) { + temp = cur.next;// 保存下一个节点 + cur.next = prev; + prev = cur; + cur = temp; + } + return prev; + } +} +``` + + +## lc24 - 两两交换链表中的节点 + +- https://programmercarl.com/0024.两两交换链表中的节点.html +- https://leetcode.com/problems/swap-nodes-in-pairs/ + +- 重要!!!!! 记忆口诀(和反转链表很类似): 举一(1个dummyHead指针!)反(反转)三(3个指针! cur! node1! node2!) +- 核心要点(和反转链表很类似): 就是需要保存一个后面可能要用的结点就弄一个指针出来, 需要两个就弄两个指针, 比如这个node1, node2 !! + +``` java +// 将步骤 2,3 交换顺序,这样不用定义 temp 节点 +public ListNode swapPairs(ListNode head) { + ListNode dummy = new ListNode(0, head); + ListNode cur = dummy; + while (cur.next != null && cur.next.next != null) { + ListNode node1 = cur.next;// 第 1 个节点 + ListNode node2 = cur.next.next;// 第 2 个节点 + cur.next = node2; // 步骤 1 + node1.next = node2.next;// 步骤 3 + node2.next = node1;// 步骤 2 + cur = cur.next.next; + } + return dummy.next; +} +``` + # 字符串 -## lc28 - 实现strStr() - 20240923 - KMP +## lc28 - 实现strStr() - 20240923 + +### 暴力解法-掌握这个暴力解法即可 + +``` java +class Solution { + public int strStr(String haystack, String needle) { + int hLen = haystack.length(); + int nLen = needle.length(); + // 0, 1, 2, 3, 4, 5 + for (int i = 0; i + nLen <= hLen; ++i) { + boolean flag = true; + for (int j = 0; j < nLen; ++j) { + if (haystack.charAt(i + j) != needle.charAt(j)) { + flag = false; + break; + } + } + if (flag == true) { + return i; + } + } + return -1; + } +} +``` +### KMP不要求-面试基本不会出的-背代码就没意思了 - https://programmercarl.com/0028.实现strStr.html#算法公开课 - https://leetcode.com/problems/find-the-index-of-the-first-occurrence-in-a-string/ @@ -183,6 +322,131 @@ class Solution { } ``` +## lc459 - 重复的子字符串-暴力解法-掌握这个暴力解法即可 + +- https://programmercarl.com/0459.重复的子字符串.html#算法公开课 +- https://leetcode.com/problems/repeated-substring-pattern/ + +``` java +// 作者:力扣官方题解 +// 链接:https://leetcode.cn/problems/repeated-substring-pattern/solutions/386481/zhong-fu-de-zi-zi-fu-chuan-by-leetcode-solution/ +class Solution { + public boolean repeatedSubstringPattern(String s) { + int n = s.length(); + for (int i = 1; i * 2 <= n; ++i) { // 这个 i 并不是 字符串的index, 而是子串长度; 并且注意到一个小优化是,因为子串至少需要重复一次,所以子串长度 i 不会大于 n 的一半, + if (n % i == 0) { // s 的长度一定是子串长度的倍数 + boolean match = true; + for (int j = i; j < n; ++j) { + int offset = j % i; // 子串肯定是 s 的前缀, 这里是拿字符串的子串前缀的index + if (s.charAt(j) != s.charAt(offset)) { + match = false; + break; + } + } + if (match) { + return true; + } + } + } + return false; + } +} +``` + +# 栈与队列 + +## lc347 - Top K Frequent Elements + +- https://leetcode.com/problems/top-k-frequent-elements/description/ +- https://programmercarl.com/0347.前K个高频元素.html#其他语言版本 +- Similar problem: https://leetcode.com/problems/kth-largest-element-in-an-array/ + +We should solve this kind of top-level problem using the “Quick Select” approach (it’s very similar to Quick Sort). Because its time complexity of O(n) is lower, this method is more efficient than the Heap-based approach with a time complexity of O(nlogn). + +Referenced this: https://www.bilibili.com/video/BV1Bz4y117Fr/ + +``` java +import java.util.Map; +import java.util.HashMap; + +class Solution { + + public static void main(String[] args) { + // int[] array = {10, 7, 8, 9, 1, 5}; + int[] array = {1, 1, 1, 1, 2, 2, 3, 3, 3, 5, 5, 5, 5, 6, 6}; + int[] res = topKFrequent(array, 2); + // int[] array = {1}; + // int[] res = topKFrequent(array, 1); + for (int num : res) { + System.out.print(num + " "); + } + } + + public static int[] topKFrequent(int[] nums, int k) { + Map map = new HashMap<>(); + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + Pair[] pairs = new Pair[map.size()]; + int index = 0; + for (Map.Entry entry : map.entrySet()) { + pairs[index++] = new Pair(entry.getKey(), entry.getValue()); + } + int partitionIndex = 0; + int pairLen = pairs.length; + int targetIndex = pairLen - k; + int low = 0; + int high = pairLen - 1; + // System.out.println(high); + while (true) { + partitionIndex = quickSelect(pairs, low, high); + if (partitionIndex == targetIndex) { + int[] res = new int[k]; + for (int i = 0; i < k; ++i) { + res[i] = pairs[--pairLen].num; + } + return res; + } else if (partitionIndex > targetIndex) { + high = partitionIndex - 1; + } else { + low = partitionIndex + 1; + } + } + } + + private static int quickSelect(Pair[] pairs, int low, int high) { + // System.out.println(low); + // System.out.println(high); + + Pair pivot = pairs[low]; + int partitionIndex = low; + + for (int i = low + 1; i <= high; ++i) { + if (pairs[i].freq < pivot.freq) { + Pair temp = pairs[i]; + pairs[i] = pairs[partitionIndex + 1]; + pairs[partitionIndex + 1] = temp; + partitionIndex++; + } + } + + pairs[low] = pairs[partitionIndex]; + pairs[partitionIndex] = pivot; + + return partitionIndex; + } + + static class Pair { + int num; + int freq; + Pair(int number, int frequency) { + num = number; + freq = frequency; + } + } +} +``` + # 二叉树 @@ -393,7 +657,7 @@ void backtracking(参数) { - https://leetcode.com/problems/combinations/ - https://programmercarl.com/0077.组合.html#算法公开课 -## 没有剪枝的版本 +### 没有剪枝的版本 ![](/img/algo_na/20201123195242899.png) @@ -403,7 +667,32 @@ class Solution { // 完全等价的, `ArrayList> resultArr = new ArrayList<>();` // - 这是Java 7引入的“钻石操作符”的用法。 // - 使用钻石操作符可以简化泛型类型的实例化,特别是当构造函数右侧的类型已经由变量声明时。 - // - 它允许编译器自动推断出泛型类型参数,从而使代码更简洁、易读。 + // - 它允许编译器自动推断出泛型类型参数,从而使代码更简洁、易读。//解法2:基于小顶堆实现 + public int[] topKFrequent2(int[] nums, int k) { + Map map = new HashMap<>(); //key为数组元素值,val为对应出现次数 + for (int num : nums) { + map.put(num, map.getOrDefault(num, 0) + 1); + } + //在优先队列中存储二元组(num, cnt),cnt表示元素值num在数组中的出现次数 + //出现次数按从队头到队尾的顺序是从小到大排,出现次数最低的在队头(相当于小顶堆) + PriorityQueue pq = new PriorityQueue<>((pair1, pair2) -> pair1[1] - pair2[1]); + for (Map.Entry entry : map.entrySet()) { //小顶堆只需要维持k个元素有序 + if (pq.size() < k) { //小顶堆元素个数小于k个时直接加 + pq.add(new int[]{entry.getKey(), entry.getValue()}); + } else { + if (entry.getValue() > pq.peek()[1]) { //当前元素出现次数大于小顶堆的根结点(这k个元素中出现次数最少的那个) + pq.poll(); //弹出队头(小顶堆的根结点),即把堆里出现次数最少的那个删除,留下的就是出现次数多的了 + pq.add(new int[]{entry.getKey(), entry.getValue()}); + } + } + } + int[] ans = new int[k]; + for (int i = k - 1; i >= 0; i--) { //依次弹出小顶堆,先弹出的是堆的根,出现次数少,后面弹出的出现次数多 + ans[i] = pq.poll()[0]; + } + return ans; + } +} ArrayList> resultArr = new ArrayList<>(); LinkedList path = new LinkedList<>(); public ArrayList> combine(int n, int k) { @@ -425,7 +714,7 @@ class Solution { } ``` -## 剪枝的版本 +### 剪枝的版本 ![](/img/algo_na/20210130194335207-20230310134409532.png) diff --git a/source/_posts/algo_newbie.md b/source/_posts/algo_newbie.md index e91732db2a..3b6c68deec 100644 --- a/source/_posts/algo_newbie.md +++ b/source/_posts/algo_newbie.md @@ -2174,7 +2174,7 @@ def _partition(arr, left_index, right_index): # partition_index 在还没开始遍历之前时应该指向待遍历元素的最左边的那个元素的前一个位置 # 在这里这种写法就是 `left_index` # 这才符合partition_index的定义: - # partition_indexy指向小于pivot的那些元素的最后一个元素, + # partition_index 指向小于pivot的那些元素的最后一个元素, # 即 less_than_pivots_last_elem_index # 因为还没找到比pivot小的元素之前, # partition_index是不应该指向任何待遍历的元素的 @@ -2183,6 +2183,7 @@ def _partition(arr, left_index, right_index): i = left_index + 1 # 因为pivot_index取left_index了, 则我们从left_index+1开始遍历 while i <= right_index: if arr[i] < pivot: + # arr[i] 和 大于pivot的第一个元素 Q 交换(Q 亦即: 小于pivot的那些元素的最后一个元素的后面一个元素, 所以是partition + 1) arr[i], arr[partition_index+1] = arr[partition_index+1], arr[i] partition_index += 1 i += 1 diff --git a/source/_posts/eng_life_youtube_interview_politics_1.md b/source/_posts/eng_life_youtube_interview_politics_1.md index 81224678a3..ffdfd21eb8 100644 --- a/source/_posts/eng_life_youtube_interview_politics_1.md +++ b/source/_posts/eng_life_youtube_interview_politics_1.md @@ -8,6 +8,11 @@ categories: --- +# URL + +https://www.youtube.com/watch?v=vgsgfy30C5g + + # English @@ -187,10 +192,7 @@ save those beautiful children you're talking  about. But instead, we're all foc 44 00:03:53,719 --> 00:03:59,358 -distracted by drag queen story. Our really. - - -## A man who insisted Trump never post a social truth. +distracted by drag queen story. Our really? Speaker 1: We need to do away with the false   @@ -212,7 +214,12 @@ but they deserve they. They get to vote. I'm not  saying you don't let them vot 49 00:04:18,079 --> 00:04:24,039 -make their vote irrelevant by turning out in  such large numbers. Here's another guy that,   +make their vote irrelevant by turning out in  such large numbers. + + +## A man who insisted Trump never post a social truth. + + Here's another guy that,   50 00:04:24,040 --> 00:04:31,160 @@ -714,9 +721,11 @@ I get extremely motivated to vote. Scary stuff.  These people are dangerous. Ve 00:03:43,159 –> 00:03:49,078 我们可以进行一些常识性的枪支改革,保护你们谈论的那些美丽孩子的生命,但结果我们都被变装故事会分散了注意力。 -## 2 Speaker 1: 我们需要摒弃那种错误的观念,即如果我们只把这些人找来,我们就能说服他们放弃他们的错觉。有些人我们可以,但在大规模的情况下,这不是我们获胜的方式。我们需要通过绕过这些人,让他们在政治上变得无关紧要,这可能不太友好,哦,但他们是有选举权的。我并不是说不让他们投票,我是说我们通过动员大量选民,使他们的选票变得无关紧要。 + +## 2 + 这是另一位卢克采访的对象,他展示了特朗普在“真相社交”上关于暂停宪法的帖子。那个人坚称那是假的,认为有人让它看起来像是特朗普发布的,但特朗普绝对不会发这种帖子。卢克给他看了,这再次证明了你给他们看了证据,他们就是不接受。他们说那是假的。 Speaker 4: 如果有人呼吁终止宪法,你会支持吗? diff --git a/source/_posts/eng_talk_show.md b/source/_posts/eng_talk_show.md new file mode 100644 index 0000000000..8054ac39bf --- /dev/null +++ b/source/_posts/eng_talk_show.md @@ -0,0 +1,12 @@ +--- +title: Working English +date: 2024-11-21 22:54:06 +tags: +- English +categories: +- English +--- + + +# English + diff --git a/source/code/test_algo_na.java b/source/code/test_algo_na.java index ca6ed7026a..4c63de2be5 100644 --- a/source/code/test_algo_na.java +++ b/source/code/test_algo_na.java @@ -1,554 +1,726 @@ -import java.util.HashSet; -import java.util.HashMap; -import java.util.Deque; -import java.util.LinkedList; -import java.util.List; -import java.util.ArrayList; -import java.util.Stack; -import java.util.Collections; -import java.util.Queue; - -// class Solution { // lc704 -// public int search(int[] numbers, int targetNumber) { -// if (targetNumber < numbers[0] || targetNumber > numbers[numbers.length -1]) { -// return -1; -// } -// int leftIndex = 0; -// int rightIndex = numbers.length -1; -// while (leftIndex <= rightIndex) { -// int midIndex = leftIndex + ((rightIndex - leftIndex) >> 2); -// if (numbers[midIndex] == targetNumber) { -// return midIndex; -// } else if (numbers[midIndex] < targetNumber) { -// leftIndex = midIndex + 1; -// } else { -// rightIndex = midIndex - 1; -// } -// } -// return -1; -// } -// } - -// class Solution { // lc27 -// public int removeElement(int[] nums, int val) { -// int newArrayIndex = 0; -// for (int searchingIndex = 0; searchingIndex < nums.length; ++searchingIndex) { -// if (nums[searchingIndex] != val) { -// nums[newArrayIndex++] = nums[searchingIndex]; -// } -// } -// return newArrayIndex; -// } +// import java.util.HashSet; +// import java.util.HashMap; +// import java.util.Deque; +// import java.util.LinkedList; +// import java.util.List; +// import java.util.ArrayList; +// import java.util.Stack; +// import java.util.Collections; +// import java.util.Queue; + +// // class Solution { // lc704 +// // public int search(int[] numbers, int targetNumber) { +// // if (targetNumber < numbers[0] || targetNumber > numbers[numbers.length -1]) { +// // return -1; +// // } +// // int leftIndex = 0; +// // int rightIndex = numbers.length -1; +// // while (leftIndex <= rightIndex) { +// // int midIndex = leftIndex + ((rightIndex - leftIndex) >> 2); +// // if (numbers[midIndex] == targetNumber) { +// // return midIndex; +// // } else if (numbers[midIndex] < targetNumber) { +// // leftIndex = midIndex + 1; +// // } else { +// // rightIndex = midIndex - 1; +// // } +// // } +// // return -1; +// // } +// // } + +// // class Solution { // lc27 +// // public int removeElement(int[] nums, int val) { +// // int newArrayIndex = 0; +// // for (int searchingIndex = 0; searchingIndex < nums.length; ++searchingIndex) { +// // if (nums[searchingIndex] != val) { +// // nums[newArrayIndex++] = nums[searchingIndex]; +// // } +// // } +// // return newArrayIndex; +// // } +// // } + +// // class Solution { // lc977 +// // public int[] sortedSquares(int[] nums) { +// // int[] resultArray = new int[nums.length]; +// // int startIndex = 0; +// // int endIndex = nums.length - 1; +// // int resultIndex = nums.length - 1; +// // while (startIndex <= endIndex) { // 这里是 <= , 因为最后要处理两个元素 +// // if (nums[startIndex] * nums[startIndex] > nums[endIndex] * nums[endIndex]) { +// // resultArray[resultIndex--] = nums[startIndex] * nums[startIndex]; +// // startIndex++; +// // } else { +// // resultArray[resultIndex--] = nums[endIndex] * nums[endIndex]; +// // endIndex--; +// // } +// // } +// // return resultArray; +// // } +// // } + + +// // class Solution { // lc209 +// // public int minSubArrayLen(int target, int[] nums) { +// // int left = 0; +// // int sum = 0; +// // int subLength = 0; +// // int result = Integer.MAX_VALUE; +// // for (int right = 0; right < nums.length; ++right) { +// // sum += nums[right]; +// // while (sum >= target) { +// // subLength = right - left + 1; +// // result = subLength > result ? result : subLength; +// // sum -= nums[left++]; +// // } +// // } +// // return result == Integer.MAX_VALUE ? 0 : result; +// // } +// // } + +// // class Solution { // lc59 +// // public int[][] generateMatrix(int n) { +// // int[][] result = new int[n][n]; +// // int loop = n / 2; +// // int startX = 0; +// // int startY = 0; +// // int num = 1; +// // int offset = 1; +// // int i, j; +// // while (loop-- > 0) { +// // i = startX; +// // j = startY; +// // for (; j < n - offset; ++j) { +// // result[i][j] = num++; +// // } +// // for (; i < n - offset; ++i) { +// // result[i][j] = num++; +// // } +// // for (; j > startX; --j) { +// // result[i][j] = num++; +// // } +// // for (; i > startY; --i) { +// // result[i][j] = num++; +// // } +// // ++startX; +// // ++startY; +// // ++offset; +// // } +// // if (n % 2 != 0) { +// // result[n/2][n/2] = n * n; +// // } +// // return result; +// // } +// // } + +// // Definition for singly-linked list. +// 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 { // lc977 -// public int[] sortedSquares(int[] nums) { -// int[] resultArray = new int[nums.length]; -// int startIndex = 0; -// int endIndex = nums.length - 1; -// int resultIndex = nums.length - 1; -// while (startIndex <= endIndex) { // 这里是 <= , 因为最后要处理两个元素 -// if (nums[startIndex] * nums[startIndex] > nums[endIndex] * nums[endIndex]) { -// resultArray[resultIndex--] = nums[startIndex] * nums[startIndex]; -// startIndex++; -// } else { -// resultArray[resultIndex--] = nums[endIndex] * nums[endIndex]; -// endIndex--; -// } -// } -// return resultArray; -// } -// } - - -// class Solution { // lc209 -// public int minSubArrayLen(int target, int[] nums) { -// int left = 0; -// int sum = 0; -// int subLength = 0; -// int result = Integer.MAX_VALUE; -// for (int right = 0; right < nums.length; ++right) { -// sum += nums[right]; -// while (sum >= target) { -// subLength = right - left + 1; -// result = subLength > result ? result : subLength; -// sum -= nums[left++]; -// } -// } -// return result == Integer.MAX_VALUE ? 0 : result; -// } -// } - -// class Solution { // lc59 -// public int[][] generateMatrix(int n) { -// int[][] result = new int[n][n]; -// int loop = n / 2; -// int startX = 0; -// int startY = 0; -// int num = 1; -// int offset = 1; -// int i, j; -// while (loop-- > 0) { -// i = startX; -// j = startY; -// for (; j < n - offset; ++j) { -// result[i][j] = num++; -// } -// for (; i < n - offset; ++i) { -// result[i][j] = num++; -// } -// for (; j > startX; --j) { -// result[i][j] = num++; -// } -// for (; i > startY; --i) { -// result[i][j] = num++; -// } -// ++startX; -// ++startY; -// ++offset; -// } -// if (n % 2 != 0) { -// result[n/2][n/2] = n * n; -// } -// return result; -// } -// } - -// Definition for singly-linked list. -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 removeElements(ListNode head, int val) { -// ListNode dummyHead = new ListNode(); -// dummyHead.next = head; -// ListNode currNode = dummyHead; -// while (currNode.next != null) { -// if (currNode.next.val == val) { -// currNode.next = currNode.next.next; -// } else { -// currNode = currNode.next; -// } -// } -// return dummyHead.next; -// } -// } - -// class MyLinkedList { +// // class Solution { +// // public ListNode removeElements(ListNode head, int val) { +// // ListNode dummyHead = new ListNode(); +// // dummyHead.next = head; +// // ListNode currNode = dummyHead; +// // while (currNode.next != null) { +// // if (currNode.next.val == val) { +// // currNode.next = currNode.next.next; +// // } else { +// // currNode = currNode.next; +// // } +// // } +// // return dummyHead.next; +// // } +// // } + +// // class MyLinkedList { -// int size; -// ListNode dummyHead; - -// public MyLinkedList() { -// size = 0; -// dummyHead = new ListNode(); -// } - -// public int get(int index) { -// if (index < 0 || index >= size) { -// return -1; -// } -// ListNode currNode = dummyHead.next; -// for (int i = 0; i <= index; ++i) { -// currNode = currNode.next; -// } -// return currNode.val; -// } - -// public void addAtHead(int val) { -// ListNode newNode = new ListNode(val); -// newNode.next = dummyHead.next; -// dummyHead.next = newNode; -// ++size; -// } - -// public void addAtTail(int val) { +// // int size; +// // ListNode dummyHead; + +// // public MyLinkedList() { +// // size = 0; +// // dummyHead = new ListNode(); +// // } + +// // public int get(int index) { +// // if (index < 0 || index >= size) { +// // return -1; +// // } +// // ListNode currNode = dummyHead.next; +// // for (int i = 0; i <= index; ++i) { +// // currNode = currNode.next; +// // } +// // return currNode.val; +// // } + +// // public void addAtHead(int val) { +// // ListNode newNode = new ListNode(val); +// // newNode.next = dummyHead.next; +// // dummyHead.next = newNode; +// // ++size; +// // } + +// // public void addAtTail(int val) { -// } +// // } -// public void addAtIndex(int index, int val) { +// // public void addAtIndex(int index, int val) { -// } +// // } -// public void deleteAtIndex(int index) { +// // public void deleteAtIndex(int index) { -// } -// } - -// // 双指针 -// class Solution { -// public ListNode reverseList(ListNode head) { -// ListNode pre = null; -// ListNode curr = head; -// ListNode temp = null; -// while (curr != null) { -// temp = curr.next; -// curr.next = pre; -// pre = curr; -// curr = temp; +// // } +// // } + +// // // 双指针 +// // class Solution { +// // public ListNode reverseList(ListNode head) { +// // ListNode pre = null; +// // ListNode curr = head; +// // ListNode temp = null; +// // while (curr != null) { +// // temp = curr.next; +// // curr.next = pre; +// // pre = curr; +// // curr = temp; +// // } +// // return pre; +// // } +// // } + +// // class Solution { +// // public ListNode swapPairs(ListNode head) { +// // if (head == null || head.next == null) { +// // return head; +// // } +// // ListNode dummyHead = new ListNode(); +// // dummyHead.next = head; + +// // ListNode currNode = dummyHead; +// // ListNode secondNode; +// // ListNode firstNode; +// // ListNode tempListNode = null; +// // while (currNode.next != null && currNode.next.next != null) { +// // firstNode = currNode.next; +// // secondNode = currNode.next.next; +// // tempListNode = secondNode.next; + +// // currNode.next = secondNode; +// // secondNode.next = firstNode; +// // firstNode.next = tempListNode; + +// // currNode = firstNode; +// // } +// // return dummyHead.next; +// // } +// // } + +// // class Solution { // lc242 +// // public boolean isAnagram(String s, String t) { +// // int[] record = new int[26]; +// // for (int i = 0; i < s.length(); ++i) { +// // record[s.charAt(i) - 'a']++; +// // } +// // for (int i = 0; i < t.length(); ++i) { +// // record[t.charAt(i) - 'a']--; +// // } +// // for (int count: record) { +// // if (count != 0) { +// // return false; +// // } +// // } +// // return true; +// // } +// // } + +// // import java.util.Set; + +// // class Solution { +// // public int[] intersection(int[] nums1, int[] nums2) { +// // HashSet testSet = new HashSet(); +// // for (int num1: nums1) { +// // testSet.add(num1); +// // } +// // HashSet resultSet = new HashSet(); +// // for (int num2: nums2) { +// // if (testSet.contains(num2) == true) { +// // resultSet.add(num2); +// // } +// // } +// // int[] resultArr = new int[resultSet.size()]; +// // int j = 0; +// // for (int i: resultSet) { +// // resultArr[j++] = i; +// // } +// // return resultArr; +// // } +// // } + +// // class Solution { +// // public boolean isHappy(int n) { +// // Set record = new HashSet<>(); +// // while (n != 1 && !record.contains(n)) { +// // record.add(n); +// // n = getNextNumber(n); +// // } +// // return n == 1; +// // } + +// // private int getNextNumber(int n) { +// // int res = 0; +// // while (n > 0) { +// // int temp = n % 10; +// // res += temp * temp; +// // n = n / 10; +// // } +// // return res; +// // } +// // } + + +// // class Solution { +// // public String reverseStr(String s, int k) { +// // char[] ch = s.toCharArray(); +// // for (int i = 0; i < ch.length; i += 2 * k) { +// // int start = i; +// // int end = Math.min(ch.length - 1, start + k - 1) +// // while (start < end) { +// // char temp = ch[start]; +// // ch[start] = ch[end]; +// // ch[end] = temp; +// // ++start; +// // --end; +// // } +// // } +// // return new String(ch); +// // } +// // } + +// //解法一 +// //自定义数组 +// class MyQueue { // lc239 +// Deque deque = new LinkedList<>(); +// //弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出 +// //同时判断队列当前是否为空 +// void poll(int val) { +// if (!deque.isEmpty() && val == deque.peek()) { +// deque.poll(); // } -// return pre; // } -// } - -// class Solution { -// public ListNode swapPairs(ListNode head) { -// if (head == null || head.next == null) { -// return head; -// } -// ListNode dummyHead = new ListNode(); -// dummyHead.next = head; - -// ListNode currNode = dummyHead; -// ListNode secondNode; -// ListNode firstNode; -// ListNode tempListNode = null; -// while (currNode.next != null && currNode.next.next != null) { -// firstNode = currNode.next; -// secondNode = currNode.next.next; -// tempListNode = secondNode.next; - -// currNode.next = secondNode; -// secondNode.next = firstNode; -// firstNode.next = tempListNode; - -// currNode = firstNode; -// } -// return dummyHead.next; +// //添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出 +// //保证队列元素单调递减 +// //比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2 +// void add(int val) { +// while (!deque.isEmpty() && val > deque.getLast()) { +// deque.removeLast(); +// } +// deque.add(val); +// } +// //队列队顶元素始终为最大值 +// int peek() { +// return deque.peek(); // } // } -// class Solution { // lc242 -// public boolean isAnagram(String s, String t) { -// int[] record = new int[26]; -// for (int i = 0; i < s.length(); ++i) { -// record[s.charAt(i) - 'a']++; -// } -// for (int i = 0; i < t.length(); ++i) { -// record[t.charAt(i) - 'a']--; -// } -// for (int count: record) { -// if (count != 0) { -// return false; -// } -// } -// return true; +// // class Solution { +// // public int[] maxSlidingWindow(int[] nums, int k) { +// // if (nums.length == 1) { +// // return nums; +// // } +// // int len = nums.length - k + 1; +// // //存放结果元素的数组 +// // int[] res = new int[len]; +// // int num = 0; +// // //自定义队列 +// // MyQueue myQueue = new MyQueue(); +// // //先将前k的元素放入队列 +// // for (int i = 0; i < k; i++) { +// // myQueue.add(nums[i]); +// // } +// // res[num++] = myQueue.peek(); +// // for (int i = k; i < nums.length; i++) { +// // //滑动窗口移除最前面的元素,移除是判断该元素是否放入队列 +// // myQueue.poll(nums[i - k]); +// // //滑动窗口加入最后面的元素 +// // myQueue.add(nums[i]); +// // //记录对应的最大值 +// // res[num++] = myQueue.peek(); +// // } +// // return res; +// // } +// // } + +// class TreeNode { +// int val; +// TreeNode left; +// TreeNode right; + +// TreeNode() {} +// TreeNode(int val) { this.val = val; } +// TreeNode(int val, TreeNode left, TreeNode right) { +// this.val = val; +// this.left = left; +// this.right = right; // } // } -// import java.util.Set; +// // class Solution { +// // public List preorderTraversal(TreeNode root) { +// // List result = new ArrayList<>(); +// // if (root == null) { +// // return result; +// // } +// // Stack stack = new Stack<>(); +// // stack.push(root); +// // while (!stack.isEmpty()) { +// // TreeNode node = stack.pop(); +// // result.add(node.val); +// // if (node.right != null) { +// // stack.push(node.right); +// // } +// // if (node.left != null) { +// // stack.push(node.left); +// // } +// // } +// // return result; +// // } +// // } + +// // class Solution { +// // public List postorderTraversal(TreeNode root) { +// // List result = new ArrayList<>(); +// // if (root == null) { +// // return result; +// // } +// // Stack stack = new Stack<>(); +// // stack.push(root); +// // while (!stack.isEmpty()) { +// // TreeNode node = stack.pop(); +// // result.add(node.val); +// // if (node.left != null) { +// // stack.push(node.left); +// // } +// // if (node.right != null) { +// // stack.push(node.right); +// // } +// // } +// // Collections.reverse(result); +// // return result; +// // } +// // } + +// // class Solution { +// // public List inorderTraversal(TreeNode root) { +// // List result = new ArrayList<>(); +// // if (root == null) { +// // return result; +// // } +// // Stack stack = new Stack<>(); +// // TreeNode cur = root; +// // while (cur != null || !stack.isEmpty()) { +// // if (cur != null) { +// // stack.push(cur); +// // cur = cur.left; // 左 +// // } else { +// // cur = stack.pop(); +// // result.add(cur.val); // 中 +// // cur = cur.right; // 右 +// // } +// // } +// // return result; +// // } +// // } + +// // class Solution { +// // public List> levelOrder(TreeNode root) { +// // List> resultList = new ArrayList>(); +// // if (root == null ) { +// // return resultList; +// // } +// // Queue que = new LinkedList(); +// // que.offer(root); + +// // while (!que.isEmpty()) { +// // List itemList = new ArrayList(); +// // int len = que.size(); + +// // while (len > 0) { +// // TreeNode tmpNode = que.poll(); +// // itemList.add(tmpNode.val); + +// // if (tmpNode.left != null) { que.offer(tmpNode.left); } +// // if (tmpNode.right != null) { que.offer(tmpNode.right); } +// // len--; +// // } +// // resultList.add(itemList); +// // } + +// // return resultList; +// // } +// // } + +// // class Solution { +// // public int maxDepth(TreeNode root) { +// // if (root == null) { +// // return 0; +// // } +// // int depth = 0; +// // Queue que = new LinkedList<>(); +// // que.offer(root); +// // while (!que.isEmpty()) { +// // int len = que.size(); +// // depth++; +// // while (len > 0) { +// // TreeNode tmpNode = que.poll(); +// // if (tmpNode.left != null) { que.offer(tmpNode.left); } +// // if (tmpNode.right != null) { que.offer(tmpNode.right); } +// // len--; +// // } +// // } +// // return depth; +// // } +// // } // class Solution { -// public int[] intersection(int[] nums1, int[] nums2) { -// HashSet testSet = new HashSet(); -// for (int num1: nums1) { -// testSet.add(num1); -// } -// HashSet resultSet = new HashSet(); -// for (int num2: nums2) { -// if (testSet.contains(num2) == true) { -// resultSet.add(num2); -// } -// } -// int[] resultArr = new int[resultSet.size()]; -// int j = 0; -// for (int i: resultSet) { -// resultArr[j++] = i; -// } +// // ArrayList> resultArr = new ArrayList<>();和 ArrayList> resultArr = new ArrayList>();有啥区别? +// // 完全等价的, `ArrayList> resultArr = new ArrayList<>();` +// // - 这是Java 7引入的“钻石操作符”的用法。 +// // - 使用钻石操作符可以简化泛型类型的实例化,特别是当构造函数右侧的类型已经由变量声明时。 +// // - 它允许编译器自动推断出泛型类型参数,从而使代码更简洁、易读。 +// ArrayList> resultArr = new ArrayList<>(); +// LinkedList path = new LinkedList<>(); +// public ArrayList> combine(int n, int k) { +// backTracking(n, k, 1); // return resultArr; // } -// } -// class Solution { -// public boolean isHappy(int n) { -// Set record = new HashSet<>(); -// while (n != 1 && !record.contains(n)) { -// record.add(n); -// n = getNextNumber(n); +// void backTracking(int n, int k, int startIndex) { +// if (path.size() == k) { +// resultArr.add(new ArrayList<>(path)); +// return; // } -// return n == 1; -// } - -// private int getNextNumber(int n) { -// int res = 0; -// while (n > 0) { -// int temp = n % 10; -// res += temp * temp; -// n = n / 10; +// for (int i = startIndex; i <= n; ++i) { +// path.add(i); +// backTracking(n, k, i+1); +// path.removeLast(); // } -// return res; // } // } -// class Solution { -// public String reverseStr(String s, int k) { -// char[] ch = s.toCharArray(); -// for (int i = 0; i < ch.length; i += 2 * k) { -// int start = i; -// int end = Math.min(ch.length - 1, start + k - 1) -// while (start < end) { -// char temp = ch[start]; -// ch[start] = ch[end]; -// ch[end] = temp; -// ++start; -// --end; -// } -// } -// return new String(ch); +// public class test_algo_na{ +// public static void main(String[] args){ +// Solution solution = new Solution(); +// // int[] myList = {1, 2, 3, 5, 6}; +// // int[][] ret = solution.generateMatrix(3); +// // System.out.println(ret); +// // for (int i = 0; i < ret.length; ++i) { +// // for (int j = 0; j < ret.length; ++j) { +// // System.out.println(ret[i][j]); +// // } +// // } +// // ListNode testList = new ListNode(1); +// // testList.next = new ListNode(2); +// // testList.next.next = new ListNode(3); +// // testList.next.next.next = new ListNode(4); + +// // // ListNode newListNode = solution.reverseList(testList); +// // ListNode newListNode = solution.swapPairs(testList); +// // while (newListNode != null) { +// // System.out.println(newListNode.val); +// // newListNode = newListNode.next; +// // } + +// // int[] myList = {1, 2, 3, 5, 6}; +// // int[] myList2 = {1, 2, 3, 4, 8, 6}; +// // int[] ret = solution.intersection(myList, myList2); + + +// // int[] myList = {1,3,-1,-3,5,3,6,7}; +// // int[] ret = solution.maxSlidingWindow(myList, 3); +// // for (int j = 0; j < ret.length; ++j) { +// // System.out.println(ret[j]); +// // } // } // } -//解法一 -//自定义数组 -class MyQueue { // lc239 - Deque deque = new LinkedList<>(); - //弹出元素时,比较当前要弹出的数值是否等于队列出口的数值,如果相等则弹出 - //同时判断队列当前是否为空 - void poll(int val) { - if (!deque.isEmpty() && val == deque.peek()) { - deque.poll(); +class ListNode { + int val; + ListNode next; + ListNode() {} + ListNode(int val) { + this.val = val; + } +} + +class MyLinkedList { + ListNode head; + + public MyLinkedList() { + head = new ListNode(0); + } + + public int get(int index) { + if (index < 0 ) { + return -1; + } + ListNode cur = head; + for (int i = 0; i <= index; ++i) { + cur = cur.next; + if (cur == null) { + return -1; + } } + return cur.val; } - //添加元素时,如果要添加的元素大于入口处的元素,就将入口元素弹出 - //保证队列元素单调递减 - //比如此时队列元素3,1,2将要入队,比1大,所以1弹出,此时队列:3,2 - void add(int val) { - while (!deque.isEmpty() && val > deque.getLast()) { - deque.removeLast(); + + public void addAtHead(int val) { + ListNode cur = new ListNode(val); + ListNode temp = head.next; + head.next = cur; + cur.next = temp; + } + + public void addAtTail(int val) { + ListNode cur = head; + while (cur.next != null) { + cur = cur.next; } - deque.add(val); + cur.next = new ListNode(val); } - //队列队顶元素始终为最大值 - int peek() { - return deque.peek(); + + public void addAtIndex(int index, int val) { + if (index < 0 ) { + return; + } + ListNode cur = head; + for (int i = 0; i < index; ++i) { + cur = cur.next; + if (cur == null) { + return; + } + } + System.out.println(cur.val); + ListNode newNode = new ListNode(val); + newNode.next = cur.next; + cur.next = newNode; + // System.out.println(cur.next.val); + // System.out.println(newNode.next.val); + } + + public void deleteAtIndex(int index) { + if (index < 0 ) { + return; + } + ListNode cur = head; + for (int i = 0; i < index; ++i) { + cur = cur.next; + if (cur == null) { + return; + } + } + if (cur.next != null) { + cur.next = cur.next.next; + } } -} - -// class Solution { -// public int[] maxSlidingWindow(int[] nums, int k) { -// if (nums.length == 1) { -// return nums; -// } -// int len = nums.length - k + 1; -// //存放结果元素的数组 -// int[] res = new int[len]; -// int num = 0; -// //自定义队列 -// MyQueue myQueue = new MyQueue(); -// //先将前k的元素放入队列 -// for (int i = 0; i < k; i++) { -// myQueue.add(nums[i]); -// } -// res[num++] = myQueue.peek(); -// for (int i = k; i < nums.length; i++) { -// //滑动窗口移除最前面的元素,移除是判断该元素是否放入队列 -// myQueue.poll(nums[i - k]); -// //滑动窗口加入最后面的元素 -// myQueue.add(nums[i]); -// //记录对应的最大值 -// res[num++] = myQueue.peek(); -// } -// return res; -// } -// } -class TreeNode { - int val; - TreeNode left; - TreeNode right; + public void print() { + ListNode cur = head.next; + while (cur != null) { + System.out.print(cur.val); + System.out.print("->"); + cur = cur.next; + } + } - TreeNode() {} - TreeNode(int val) { this.val = val; } - TreeNode(int val, TreeNode left, TreeNode right) { - this.val = val; - this.left = left; - this.right = right; + public ListNode swapPairs() { + int i = 1; + ListNode cur = head.next; + ListNode pre = null; + ListNode prePre = null; + ListNode temp = null; + ListNode finalHead = cur; + while (cur != null) { + if (i % 2 != 0) { + pre = cur; + System.out.println("yyyy"); + // System.out.println(i); + System.out.println(pre.val); + System.out.println("iiii"); + cur = cur.next; + } else { + if (i == 2) { + finalHead = cur; + System.out.println("fff"); + System.out.println(finalHead.val); + System.out.println("aaa"); + } + temp = cur.next; + cur.next = pre; + pre.next = temp; + if (prePre != null) { + prePre.next = cur; + } + prePre = pre; + cur = temp; + } + ++i; + } + head.next = finalHead; + return finalHead; } } -// class Solution { -// public List preorderTraversal(TreeNode root) { -// List result = new ArrayList<>(); -// if (root == null) { -// return result; -// } -// Stack stack = new Stack<>(); -// stack.push(root); -// while (!stack.isEmpty()) { -// TreeNode node = stack.pop(); -// result.add(node.val); -// if (node.right != null) { -// stack.push(node.right); -// } -// if (node.left != null) { -// stack.push(node.left); -// } -// } -// return result; -// } -// } - -// class Solution { -// public List postorderTraversal(TreeNode root) { -// List result = new ArrayList<>(); -// if (root == null) { -// return result; -// } -// Stack stack = new Stack<>(); -// stack.push(root); -// while (!stack.isEmpty()) { -// TreeNode node = stack.pop(); -// result.add(node.val); -// if (node.left != null) { -// stack.push(node.left); -// } -// if (node.right != null) { -// stack.push(node.right); -// } -// } -// Collections.reverse(result); -// return result; -// } -// } - -// class Solution { -// public List inorderTraversal(TreeNode root) { -// List result = new ArrayList<>(); -// if (root == null) { -// return result; -// } -// Stack stack = new Stack<>(); -// TreeNode cur = root; -// while (cur != null || !stack.isEmpty()) { -// if (cur != null) { -// stack.push(cur); -// cur = cur.left; // 左 -// } else { -// cur = stack.pop(); -// result.add(cur.val); // 中 -// cur = cur.right; // 右 -// } -// } -// return result; -// } -// } - -// class Solution { -// public List> levelOrder(TreeNode root) { -// List> resultList = new ArrayList>(); -// if (root == null ) { -// return resultList; -// } -// Queue que = new LinkedList(); -// que.offer(root); - -// while (!que.isEmpty()) { -// List itemList = new ArrayList(); -// int len = que.size(); - -// while (len > 0) { -// TreeNode tmpNode = que.poll(); -// itemList.add(tmpNode.val); - -// if (tmpNode.left != null) { que.offer(tmpNode.left); } -// if (tmpNode.right != null) { que.offer(tmpNode.right); } -// len--; -// } -// resultList.add(itemList); -// } - -// return resultList; -// } -// } - -// class Solution { -// public int maxDepth(TreeNode root) { -// if (root == null) { -// return 0; -// } -// int depth = 0; -// Queue que = new LinkedList<>(); -// que.offer(root); -// while (!que.isEmpty()) { -// int len = que.size(); -// depth++; -// while (len > 0) { -// TreeNode tmpNode = que.poll(); -// if (tmpNode.left != null) { que.offer(tmpNode.left); } -// if (tmpNode.right != null) { que.offer(tmpNode.right); } -// len--; -// } -// } -// return depth; -// } -// } - class Solution { - // ArrayList> resultArr = new ArrayList<>();和 ArrayList> resultArr = new ArrayList>();有啥区别? - // 完全等价的, `ArrayList> resultArr = new ArrayList<>();` - // - 这是Java 7引入的“钻石操作符”的用法。 - // - 使用钻石操作符可以简化泛型类型的实例化,特别是当构造函数右侧的类型已经由变量声明时。 - // - 它允许编译器自动推断出泛型类型参数,从而使代码更简洁、易读。 - ArrayList> resultArr = new ArrayList<>(); - LinkedList path = new LinkedList<>(); - public ArrayList> combine(int n, int k) { - backTracking(n, k, 1); - return resultArr; - } - - void backTracking(int n, int k, int startIndex) { - if (path.size() == k) { - resultArr.add(new ArrayList<>(path)); - return; + public int mySqrt(int x) { + if (x == 0 || x == 1) { + return x; } - for (int i = startIndex; i <= n; ++i) { - path.add(i); - backTracking(n, k, i+1); - path.removeLast(); + int left = 1; + int right = x; + int mid = 0; + while (left <= right) { + mid = left + (right - left) / 2; + System.out.println("mid="+mid); + if ((long)mid * mid > x) { + right = mid - 1; + System.out.println("right="+right); + } else if ((long)mid * mid < x) { + left = mid + 1; + System.out.println("left="+left); + } else { + return mid; + } } + return right; } } - public class test_algo_na{ public static void main(String[] args){ - Solution solution = new Solution(); - // int[] myList = {1, 2, 3, 5, 6}; - // int[][] ret = solution.generateMatrix(3); - // System.out.println(ret); - // for (int i = 0; i < ret.length; ++i) { - // for (int j = 0; j < ret.length; ++j) { - // System.out.println(ret[i][j]); - // } - // } - // ListNode testList = new ListNode(1); - // testList.next = new ListNode(2); - // testList.next.next = new ListNode(3); - // testList.next.next.next = new ListNode(4); - - // // ListNode newListNode = solution.reverseList(testList); - // ListNode newListNode = solution.swapPairs(testList); - // while (newListNode != null) { - // System.out.println(newListNode.val); - // newListNode = newListNode.next; - // } - - // int[] myList = {1, 2, 3, 5, 6}; - // int[] myList2 = {1, 2, 3, 4, 8, 6}; - // int[] ret = solution.intersection(myList, myList2); - - - // int[] myList = {1,3,-1,-3,5,3,6,7}; - // int[] ret = solution.maxSlidingWindow(myList, 3); - // for (int j = 0; j < ret.length; ++j) { - // System.out.println(ret[j]); - // } + + // Your MyLinkedList object will be instantiated and called as such: + // MyLinkedList myLinkedList = new MyLinkedList(); + // myLinkedList.addAtTail(1); + // myLinkedList.addAtTail(2); + // myLinkedList.addAtTail(3); + // myLinkedList.addAtTail(4); + // myLinkedList.print(); + // System.out.println("****"); + // myLinkedList.swapPairs(); + // myLinkedList.print(); + // System.out.println("****"); + + Solution ss = new Solution(); + System.out.println(ss.mySqrt(8)); } -} \ No newline at end of file +}