简单记录一下最近的状态,最近一直做着与工作相关的一些事情,每天学习,不会就学呗,没有什么是学不会的,踏踏实实的努力就好了。
个人的技术方向做一个Java的后端开发,随后想着做大数据分析或者做一些3D的游戏,自己也是在慢慢的摸索着,个人的联系方式itxingzai@163.com,希望有相同兴趣的可以一起交流,做一个安分的技术人,好了,看看今天的算法题目吧。
题目一 机器人能否回到起点
题目一描述
在一个二维的平面上,有一个机器人从原点(0,0)处开始移动,判断该机器人是否在移动结束后会回到原点。机器人有四个动作,UDLR(表示上下左右),给定一个路径字符串,如果能够回到原点,返回true,否则返回false。
例如:
输入: UD
返回:true
表示先向上走一步,再向下走一步,回到了原点
题目传送门
题目一分析
机器人只有四个方向的移动,因此在相对的位置上如果走相同的步数那么就可以回到原始的位置,只要有任意相对位置不是相同的步数,那么就回不到原始位置。
比如:向右走5步,向上走8步,向左走5步向下走8步,这个一定可以回到起始位置。
设计算法,使用一个变量row记录机器人走的左右路径的步数,向左走+1,向右走-1
使用另一个变量记录col机器人走的上下路线的步数,向上走+1,向下走-1
最后只要有一个变量不为0即在某个方向偏离原点的位置
代码如下
class Solution {
public boolean judgeCircle(String moves) {
int index = 0;
//水平方向、垂直方向的变量
int row = 0;
int col = 0;
for(;index<moves.length();index++){
char ch = moves.charAt(index);
//计算两个方向的偏移量
switch (ch){
case 'L':
row++;break;
case 'R':
row--;break;
case 'U':
col++;break;
case 'D':
col--;break;
}
}
//只要有一个方向有偏移,则返回false
if(col!=0||row!=0)return false;
return true;
}
}
题目二 删除链表中倒数第N个节点
题目二描述
给定一个链表,和一个整数n要求删除链表中倒数第n个节点,并返回链表的头结点
输入:1->2->3->4->5 和n = 2
输出:1->2->3->5
题目二分析
链表数据结构,其优点在于其插入和删除元素快,不用提前指定空间大小,其缺点是查找慢,因为链表只有头结点有记录,其余节点只能根据头结点进行查找。
对于链表的题目个人总结是:大部分的题目都可以使用双指针解决链表问题,例如:链表成环等。该题目使用双指针计算,时间复杂度为O(n),要删除倒数第n个节点,必须记录倒数第n+1个节点的位置,然后将其指向要删除节点的下一个位置即可。
代码如下
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode slow = new ListNode(-1);
slow.next=head;
ListNode fast = head;
ListNode res = slow;
int i=0;
//快指针先走n步,与慢指针形成一个n+1的窗
//引入头结点是因为,第一个位置也有可能会被删除
for(;i<n;i++){
if(fast==null)break;
fast = fast.next;
}
if(i<n&&fast==null)return null;
//两个指针一起走,维持窗的大小,直到最后
while(fast!=null){
slow = slow.next;
fast = fast.next;
}
//根据倒数第n+1的位置删除倒数n的位置
slow.next = slow.next.next;
return res.next;
}
}
题目三 括号生成
题目三描述
给定一个整数n,表示是n对括号,输出为所有有效地括号的字符串组合
例如:
输入:3
输出:[ " ((()))","(())()","(()())","()(())","()()()" ]
题目传送
题目三分析
回溯法,也就是一个递归的过程,递归过程涉及到的是递归的出口,递归的参数以及条件,这个其实理解不是很深,自己看的官网的思想。
代码如下
class Solution {
public List<String> generateParenthesis(int n) {
List<String> list = new ArrayList<>();
getString(list,new StringBuilder(),0,0,n);
return list;
}
//输入一个集合用于存储符合要求的字符串,输入字符串,输入左括号数量,输入右括号数量,输入给定的整数
public void getString(List<String> list,StringBuilder sb,int left,int right,int n){
//递归结束条件,当前的字符串满足长度的要求,将其加入到集合中
if(sb.length()==2*n){
list.add(sb.toString());
return;
}
//当左括号没达到最大值,将左括号加入字符串中,递归子过程后,进行剪枝操作,将字符串最后元素删除
if(left<n){
sb.append('(');
getString(list,sb,left+1,right,n);
sb.deleteCharAt(sb.length()-1);
}
//如果右括号比左括号多,一定不符合条件
if(right<left){
//符合条件将右括号加入字符串中,递归右过程,剪枝操作,回溯
sb.append(')');
getString(list,sb,left,right+1,n);
sb.deleteCharAt(sb.length()-1);
}
}
}