刷题记录及题目理解
完成题目编号:69、241、160、1、242
一.题目编号:69
- 题目描述
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例1:
输入: 4 输出: 2。
示例2:
输入: 8 输出: 2 说明: 8 的平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
- 题目理解
返回类型是整数,小数部分将被舍去 3. 逻辑思路 可以将输入的参数分解成两数乘积,其中一个乘数容易求得平方根,另一个乘数可以通过递归思想继续求解。 4. 优解代码
class Solution {
public int mySqrt(int x) {
if(x<2){
return x;
}else{
//将输入的数字位右移2位,缩小2^2倍,求得平方根之后左移1位,扩大2^1倍
int low = mySqrt(x>>2)<<1;
int high = low+1;
return (long) high*high>x?low:high;
}
}
}
- 优解理解
本方法的思路是使用递归,每一步都减小 x,直到 x < 2。当 x < 2 时有 sqrt(x)= x
无需减小。 当 x >= 2 时,减小方法如下:Sqrt(x) = 2 * Sqrt ( x / 4 )
- 总结 递归思想理解起来简单,代码实现难。
二、题目编号:241
- 题目描述
给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, - 以及 * 。
示例1:
输入: "2-1-1" 输出: [0, 2] 解释: ((2-1)-1) = 0 (2-(1-1)) = 2
示例2:
输入: "2 * 3 - 4 * 5" 输出: [-34, -14, -10, -10, 10] 解释: (2*(3 - (4 * 5))) = -34 ((2 * 3)-(4 * 5)) = -14 ((2 * (3-4)) * 5) = -10 (2 * ((3-4)*5)) = -10 (((2 * 3)-4)*5) = 10
- 题目理解 利用运算符将表达式分隔成多段,利用分治法缩减问题规模,无运算符的单个数字可直接输出成结果。
- 逻辑思路 分治法:partition方法,然后递归
- 优解代码
class Solution {
public List<Integer> diffWaysToCompute(String input) {
List<Integer> result = new ArrayList<>();
if (!input.contains("+") && !input.contains("-") && !input.contains("*")) {
result.add(Integer.valueOf(input));
return result;
}
for(int i = 0; i < input.length(); i++) {
if (input.charAt(i) == '+' || input.charAt(i) == '-' || input.charAt(i) == '*') {
for(Integer left : diffWaysToCompute(input.substring(0, i))) {
for (Integer right : diffWaysToCompute(input.substring(i + 1))) {
if (input.charAt(i) == '+') {
result.add(left + right);
} else if (input.charAt(i) == '-') {
result.add(left - right);
} else if (input.charAt(i) == '*') {
result.add(left * right);
}
}
}
}
}
return result;
}
}
-
优解理解 基性条件:代表问题简化到一定程度,可以进行递归操作的条件,当表达式被分解出无运算符的状态时,可以直接把操作数输出,作为结果。
-
总结 实现递归难啊。
三、题目编号:160
- 题目描述
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:

示例1:

-
题目理解 对于示例1,之所以1不是相交节点,因为两个元素1本身所在的地址值不同
-
逻辑思路 对于链表,存在value和下一个元素的next指针。
-
优解代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode pa = headA;
ListNode pb = headB;
while(pa != pb){
pa = pa ==
}
}
}
-
优解理解 pa指针走了A链表+B链表的长度,pb指针走了B链表+A链表的长度,ListNode的比较,需要同时比较value和next。
-
问题代码思路 链表不熟悉。
-
总结 无话可说
四、题目编号:1
- 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1]
- 题目理解 返回数组下标, 可以从0开始。
- 逻辑思路 哈希表方法,将输入数组存入K,判断其是否符合目标元素,同时,在V处存储索引。
- 优解代码
class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> hashMap = new HashMap();
for(int i =0;i<nums.length;i++){
if(hashMap.containsKey(target - nums[i])){
return new int[] {hashMap.get(target-nums[i]),i} ;
}
hashMap.put(nums[i],i);
}
return new int[]{-1,-1};
}
}
-
优解理解 存入key值的时候,即进行判断
-
总结
五、题目编号:242
- 题目描述 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。 说明:
你可以假设字符串只包含小写字母。
示例1:
输入: s = "anagram", t = "nagaram" 输出: true
示例2:
输入: s = "rat", t = "car" 输出: false
进阶:
如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?
- 题目理解 不理解包含大写字母存在哪些问题,包含unicode字符应该也没问题
- 逻辑思路 创建哈希表,K值存字符串字节,V值存出现次数,然后,对第二个字符串参数处理,K存在的字节,V值减1。
- 优解代码
class Solution {
public boolean isAnagram(String s, String t) {
if(s.length() !=t.length()){
return false;
}
HashMap<Character,Integer> hashMap = new HashMap();
for(int i =0;i<s.length();i++){
hashMap.put(s.charAt(i),hashMap.getOrDefault(s.charAt(i),0)+1);
hashMap.put(t.charAt(i),hashMap.getOrDefault(t.charAt(i),0)-1);
}
for(int i:hashMap.values()){
if(i!=0){
return false;
}
}
return true;
}
}
-
优解理解 创建两个哈希表麻烦
-
总结