每日算法(2021/9/24)
从今天开始每日算法,目的是熟悉语言语法结构,也为了能够提高自己的编码能力,会用多种语言,当然逻辑相通。
平台基于leetcode平台,会从基础开始,每天3简单,2中等,1困难。(之后会提量,现在做的比较慢,第一天做了五道简单练手,后面会回到正常)
不知道能保持多久,总之尽量。
会给出题目名称,不给出内容只给题解。
以下。
1.Tow Sum(两数之和)简单
看到这道题,第一时间想到的当然是遍历,那么为了能够高速遍历我们就需要用到哈希表(哈希为什么告诉请自行查询,总来说是因为能够指向性直接读取内存)。
java:
class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer,Integer> map = new HashMap();//创建哈希表 for(int i=0;i<nums.length;i++ )//遍历nums内的数据 { if(map.containsKey(target-nums[i]))//判断是否存在两数之和等于terget,利用的是key值的查找 return new int[] {map.get(target-nums[i]),i};//存在则返回,不存在加入map继续遍历 map.put(nums[i],i); } throw new IllegalArgumentException("No Two Sum Solution");//抛出异常 } }
速度也是非常的快(后面那个抛异常是看的题解23333)。
2.Reverse Integer(整数反转)简单
java:
class Solution { public int reverse(int x) { int res = 0;//存储结论数 while(x!=0){//考虑循环取模后相加 int tmp = x%10;//循环取模。本题核心 if(res>214748364 || (res==214748364 && tmp>7))//范围判断 return 0; if(res<-214748364 || (res==-214748364 && tmp<-8))//一开始这两个判断写在了一起,后来想了想第一个判断语句与后一句有关,大量判断明显是无效的,所以分开可以降低平均数。 return 0; x=x/10; res = tmp+res*10; } return res; } }
第一次提交没算res,有笑到自己。
3.Palindrome Number(回文数)简单
第一反应最简单的是通过指针,将数据打散放入数组,指针前后挨个对照。
缺点明显,占用空间大,效率低。
观察回文数特征,后一半的数反向排列与前一半数相同,那么我们可以挨个取出来,乘以相应倍率,然后和前一半对比(假设是偶数位数),奇数只要前面或者后面进行一个取模再比较即可。
java:
class Solution { public boolean isPalindrome(int x) { if(x>0&&x<10) return true;//显然是回文 if (x < 0 || (x % 10 == 0 && x != 0)) return false;//显然不是 int reverted = 0; while (x > reverted) { reverted = reverted * 10 + x % 10; x /= 10; }//进行前后半段对照 return x == reverted || x == reverted / 10;//该方法的优势在于内存消耗,速率有一定损失但是不大 } }
python3:
class Solution: def isPalindrome(self, x: int) -> bool: return True if str(x) == str(x)[::-1] else False
本来都想用python,但是不知道为什么if语句的退格一直出问题,python自带有字符串反转语句,可以调用。
4.Roman to Integer(罗马数字转整数)简单
这个没什么可说的,主要是在意一下右边恒正这个问题,我自己做的时候最后没加num导致第一次提交错误hhh。
5.longest common prefix(最长公共前缀)简单
java
近乎是循环遍历的方式。
6.Add Tow Numbers(两数相加)中等
java:
/** * 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 addTwoNumbers(ListNode l1, ListNode l2) { ListNode pre = new ListNode(0);//创建两个“指针”用于定位 ListNode pre2 = pre; int carry = 0;//存放进位 while(l1 != null || l2 != null)//判断循环是两者皆空 { int x = l1 == null ? 0 : l1.val;//取值 int y = l2 == null ? 0 : l2.val;//取值 int sum = x + y + carry;//相加并且获得进位 carry = sum >9 ? 1 : 0;//判断是否存在进位 sum = sum % 10;//进位去除 pre2.next = new ListNode(sum); pre2 = pre2.next; if(l1 != null) l1 = l1.next; if(l2 != null) l2 = l2.next; } if(carry == 1) {//判断是否需要加节点 pre2.next = new ListNode(carry); } return pre.next; } }
缺点是新建链表了,其实可以直接放在其中一个表中用于节省空间。
7.Longest Substring Without Repeating Characters(无重复字符的最长字串)中等
class Solution { public int lengthOfLongestSubstring(String s) { if (s.length()==0) return 0;//总忘记写这个 HashMap<Character,Integer> map = new HashMap();//题解中有一个称呼为“滑动窗口”我也不知道怎么称呼合适,这个蛮形象的。 int max = 0;//记录结果 int left = 0;//记录窗口左边界 for(int i=0;i<s.length();i++){ if(map.containsKey(s.charAt(i))){//哈希查重 left = Math.max(left,map.get(s.charAt(i)) + 1);//核心语句,边界移动 } map.put(s.charAt(i),i); max = Math.max(max,i-left+1); } return max; } }
8.Median of Tow Sorted Arrays(两个正序数组的中位数)
class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { int n = nums1.length; int m = nums2.length; int left = (n + m + 1) / 2; int right = (n + m + 2) / 2; return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5; } private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) { int len1 = end1 - start1 + 1; int len2 = end2 - start2 + 1; if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k); if (len1 == 0) return nums2[start2 + k - 1]; if (k == 1) return Math.min(nums1[start1], nums2[start2]); int i = start1 + Math.min(len1, k / 2) - 1; int j = start2 + Math.min(len2, k / 2) - 1; if (nums1[i] > nums2[j]) { return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1)); } else { return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1)); } } }
这里采用了两个数组同切的方式,能够在不开辟新空间的情况下采用二分法进行分割判断。
奇偶合并参考题解,自己脑子没转过来(。
效率还可以,题解有一个法4我没太理解,法3和我这个一样。
本题难点在于如何进行二分法切割,在不开辟新空间的情况下进行大小比对得出中位数,采用了k/2然后对小数删除的筛选思想得到中位数解。
2021/9/24总结:
很久没有写算法题了,leetcode是一个不错的平台,首日写了8题用了2-3小时,时长较长。
考虑原因的话,一是没有IDE纠正语法与提示,明显降低了代码效率,很多函数蒙住不会拼写hhhh。
二是算法题很多时间在于题目分析,做题较少的情况下分析速度慢,想要提高代码效率的话还是应该先写下来然后逐步改进,我这里更多想要一步到位,只能一定程度上保证效率。
不过我写算法的目的是能够快速理解算法结构,方便代码审计阅读,也方便自己进行开发,入门路且长。

浙公网安备 33010602011771号