哈希
1、创建
//创建一个 HashMap 对象 Sites, 整型(Integer)的 key 和字符串(String)类型的 value
HashMap<Integer, String> Sites = new HashMap<Integer, String>();
2、常用函数
//put() 方法将指定的键/值对插入到 HashMap 中。
HashMap<Integer, String> sites = new HashMap<>();
// 往 HashMap 添加一些元素
sites.put(1, "Google");
sites.put(2, "Runoob");
// 获得该 HashMap 中键/值对映射的数量
int size = sites.size();
// 得到 value
String value = sites.get(1);
// 替换key为2的映射
String value = sites.replace(2, "Wiki");
// 删除key为2的映射关系
String siteName = sites.remove(2); // return Wiki
//检查 key 为 4 是否存在,不存在插入该 key/value 对
// 使用 ! 符号来对布尔结果取相反的值
if(!sites.containsKey(4)) {
sites.put(4, "Wiki");
}
//检查映射中值value是否有Java
if(sites.containsValue("Runoob")) {
System.out.println("Runoob 存在于 sites 中");
}
链表
1、表示
//定义HeroNode , 每个HeroNode 对象就是一个节点
class HeroNode {
public int no;
public String name;
public String nickname;
public HeroNode next; //指向下一个节点
//构造器
public HeroNode(int no, String name, String nickname) {
this.no = no;
this.name = name;
this.nickname = nickname;
}
//为了显示方法,我们重新toString
@Override
public String toString() {
return "HeroNode [no=" + no + ", name=" + name + ", nickname=" + nickname + "]";
}
}
2、链表遍历
//显示链表[遍历]
public void list() {
//判断链表是否为空
if(head.next == null) {
System.out.println("链表为空");
return;
}
//因为头节点,不能动,因此我们需要一个辅助变量来遍历
HeroNode temp = head.next;
while(true) {
//判断是否到链表最后
if(temp == null) {
break;
}
//输出节点的信息
System.out.println(temp);
//将temp后移, 一定小心
temp = temp.next;
}
}
}
3、删除
//删除节点
//思路
//1. head 不能动,因此我们需要一个temp辅助节点找到待删除节点的前一个节点
//2. 说明我们在比较时,是temp.next.no 和 需要删除的节点的no比较
public void del(int no) {
HeroNode temp = head;
boolean flag = false; // 标志是否找到待删除节点的
while(true) {
if(temp.next == null) { //已经到链表的最后
break;
}
if(temp.next.no == no) {
//找到的待删除节点的前一个节点temp
flag = true;
break;
}
temp = temp.next; //temp后移,遍历
}
//判断flag
if(flag) { //找到
//可以删除
temp.next = temp.next.next;
}else {
System.out.printf("要删除的 %d 节点不存在\n", no);
}
}
4、修改链表信息
//修改节点的信息, 根据no编号来修改,即no编号不能改.
//说明
//1. 根据 newHeroNode 的 no 来修改即可
public void update(HeroNode newHeroNode) {
//判断是否空
if(head.next == null) {
System.out.println("链表为空~");
return;
}
//找到需要修改的节点, 根据no编号
//定义一个辅助变量
HeroNode temp = head.next;
boolean flag = false; //表示是否找到该节点
while(true) {
if (temp == null) {
break; //已经遍历完链表
}
if(temp.no == newHeroNode.no) {
//找到
flag = true;
break;
}
temp = temp.next;
}
//根据flag 判断是否找到要修改的节点
if(flag) {
temp.name = newHeroNode.name;
temp.nickname = newHeroNode.nickname;
} else { //没有找到
System.out.printf("没有找到 编号 %d 的节点,不能修改\n", newHeroNode.no);
}
}
面试题1
查找单链表中的倒数第k个结点 【新浪面试题】
本人思路 | 题解思路 |
---|---|
1、遍历单链表 2、两个辅助指针,第一个指针遍历到第k个时,第二个指针开始遍历,当第一个的next指向空时,第二个指针指向倒数k的位置 3、输出第二个指针内容 |
1. 编写一个方法,接收head节点,同时接收一个index 2. index 表示是倒数第index个节点 3. 先把链表从头到尾遍历,得到链表的总的长度 getLength 4. 得到size 后,我们从链表的第一个开始遍历 (size-index)个,就可以得到 5. 如果找到了,则返回该节点,否则返回nulll |
更加容易理解 |
public static HeroNode findLastIndexNode(HeroNode head, int index) {
//判断如果链表为空,返回null
if(head.next == null) {
return null;//没有找到
}
//第一个遍历得到链表的长度(节点个数)
int size = getLength(head);
//第二次遍历 size-index 位置,就是我们倒数的第K个节点
//先做一个index的校验
if(index <=0 || index > size) {
return null;
}
//定义给辅助变量, for 循环定位到倒数的index
HeroNode cur = head.next; //3 // 3 - 1 = 2
for(int i =0; i< size - index; i++) {
cur = cur.next;
}
return cur;
}
//方法:获取到单链表的节点的个数(如果是带头结点的链表,需求不统计头节点)
/**
*
* @param head 链表的头节点
* @return 返回的就是有效节点的个数
*/
public static int getLength(HeroNode head) {
if(head.next == null) { //空链表
return 0;
}
int length = 0;
//定义一个辅助的变量, 这里我们没有统计头节点
HeroNode cur = head.next;
while(cur != null) {
length++;
cur = cur.next; //遍历
}
return length;
}
}
类似题:删除链表的倒数第n个节点
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param n int整型
* @return ListNode类
*/
public ListNode removeNthFromEnd (ListNode head, int n) {
ListNode cur = head;
ListNode cur2=head;
if(head.next == null) return null;
//只有一个节点,根据题目,n合法,所以肯定删去这个节点
for(int i=0;i<n;i++){
cur=cur.next;
}
if(cur == null)//待删除节点是头节点
return head.next;
while(cur.next!=null){
cur=cur.next;
cur2=cur2.next;
}
cur2.next=cur2.next.next;
return head;
}
}
考题2
链表合并:将两个有序的链表合并为一个新链表,要求新的链表是通过拼接两个链表的节点来生成的,且合并后新链表依然有序。
字符串
字符串替换replace()
public class Main {
public static void main(String args[]) {
String Str = new String("Runoob");
System.out.print("返回值 :" );
System.out.println(Str.replace('o', 'T'));
System.out.print("返回值 :" );
System.out.println(Str.replace('u', 'D'));
}
}
//返回值 :RunTTb
//返回值 :RDnoob
charAt
public char charAt(int index)
public class Test {
public static void main(String args[]) {
String s = "www.runoob.com";
char result = s.charAt(6);
System.out.println(result);
}
}
转换为字符数组
public class Test {
public static void main(String args[]) {
String Str = new String("www.runoob.com");
System.out.print("返回值 :" );
System.out.println( Str.toCharArray() );
}
}
动态规划
求解步骤:
a. 找出最优解的性质,并刻划其结构特征。
b. 递归地定义最优值。
c. 以自底向上的方式计算出最优值。
d. 根据计算最优值时得到的信息,构造最优解
放苹果
最长回文数
机器人走路
一个机器人在m×n大小的地图的左上角(起点)。
机器人每次向下或向右移动。机器人要到达地图的右下角(终点)。
可以有多少种不同的路径从起点走到终点?
首先,我们可以发现第一行和第一列的位置只能有一种方法到达
对于其它位置来说,到达这个位置有两种情况:
一种是从上面的格子走过来的
另一种是从左边的格子走过来的
所以,我们定义一个𝑚×𝑛大小的二维数组𝑑𝑝
𝑑𝑝[𝑖][𝑗]表示从起点到达第𝑖行第𝑗列的方案数。
先把第一行第一列赋值为1
然后从第二行第二列的元素开始循环
𝑑𝑝[𝑖][𝑗]=𝑑𝑝[𝑖−1][𝑗]+𝑑𝑝[𝑖][𝑗−1]
右下角的dp值就是我们要求的答案